diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h index 65a2bb116eb..2da4ba0dbfb 100644 --- a/js/public/ProfilingFrameIterator.h +++ b/js/public/ProfilingFrameIterator.h @@ -43,11 +43,10 @@ class JS_PUBLIC_API(ProfilingFrameIterator) public: struct RegisterState { + RegisterState() : pc(nullptr), sp(nullptr), lr(nullptr) {} void *pc; void *sp; -#if defined(JS_CODEGEN_ARM) void *lr; -#endif }; ProfilingFrameIterator(JSRuntime *rt, const RegisterState &state); @@ -62,19 +61,9 @@ class JS_PUBLIC_API(ProfilingFrameIterator) // and less than older native and psuedo-stack frame addresses void *stackAddress() const; - enum Kind { - Function, - AsmJSTrampoline, - CppFunction - }; - Kind kind() const; - - // Methods available if kind() == Function: - JSAtom *functionDisplayAtom() const; - const char *functionFilename() const; - - // Methods available if kind() != Function - const char *nonFunctionDescription() const; + // Return a label suitable for regexp-matching as performed by + // browser/devtools/profiler/cleopatra/js/parserWorker.js + const char *label() const; }; } // namespace JS diff --git a/js/src/jit-test/tests/asm.js/testProfiling.js b/js/src/jit-test/tests/asm.js/testProfiling.js index af7ccdee1b8..b027704f1f0 100644 --- a/js/src/jit-test/tests/asm.js/testProfiling.js +++ b/js/src/jit-test/tests/asm.js/testProfiling.js @@ -4,6 +4,17 @@ load(libdir + "asm.js"); if (!getBuildConfiguration()["arm-simulator"]) quit(); +function assertEqualStacks(got, expect) +{ + // Strip off the " (script/library info)" + got = String(got).replace(/ \([^\)]*\)/g, ""); + + // Shorten FFI/entry trampolines + got = got.replace(/FFI trampoline/g, "<").replace(/entry trampoline/g, ">"); + + assertEq(got, expect); +} + // Test profiling enablement while asm.js is running. var stacks; var ffi = function(enable) { @@ -16,15 +27,15 @@ var ffi = function(enable) { } var f = asmLink(asmCompile('global','ffis',USE_ASM + "var ffi=ffis.ffi; function g(i) { i=i|0; ffi(i|0) } function f(i) { i=i|0; g(i|0) } return f"), null, {ffi}); f(0); -assertEq(String(stacks), ""); +assertEqualStacks(stacks, ""); f(+1); -assertEq(String(stacks), ""); +assertEqualStacks(stacks, ""); f(0); -assertEq(String(stacks), "*gf*"); +assertEqualStacks(stacks, ""); f(-1); -assertEq(String(stacks), "*gf*"); +assertEqualStacks(stacks, ""); f(0); -assertEq(String(stacks), ""); +assertEqualStacks(stacks, ""); // Enable profiling for the rest of the tests. enableSPSProfiling(); @@ -33,27 +44,27 @@ var f = asmLink(asmCompile(USE_ASM + "function f() { return 42 } return f")); enableSingleStepProfiling(); assertEq(f(), 42); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f*,*,"); +assertEqualStacks(stacks, ",>,f>,>,"); var f = asmLink(asmCompile(USE_ASM + "function g(i) { i=i|0; return (i+1)|0 } function f() { return g(42)|0 } return f")); enableSingleStepProfiling(); assertEq(f(), 43); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f*,gf*,f*,*,"); +assertEqualStacks(stacks, ",>,f>,gf>,f>,>,"); var f = asmLink(asmCompile(USE_ASM + "function g1() { return 1 } function g2() { return 2 } function f(i) { i=i|0; return TBL[i&1]()|0 } var TBL=[g1,g2]; return f")); enableSingleStepProfiling(); assertEq(f(0), 1); assertEq(f(1), 2); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f*,g1f*,f*,*,,*,f*,g2f*,f*,*,"); +assertEqualStacks(stacks, ",>,f>,g1f>,f>,>,,>,f>,g2f>,f>,>,"); function testBuiltinD2D(name) { var f = asmLink(asmCompile('g', USE_ASM + "var fun=g.Math." + name + "; function f(d) { d=+d; return +fun(d) } return f"), this); enableSingleStepProfiling(); assertEq(f(.1), eval("Math." + name + "(.1)")); var stacks = disableSingleStepProfiling(); - assertEq(String(stacks), ",*,f*,Math." + name + "f*,f*,*,"); + assertEqualStacks(stacks, ",>,f>,Math." + name + "f>,f>,>,"); } for (name of ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'ceil', 'floor', 'exp', 'log']) testBuiltinD2D(name); @@ -62,7 +73,7 @@ function testBuiltinF2F(name) { enableSingleStepProfiling(); assertEq(f(.1), eval("Math.fround(Math." + name + "(Math.fround(.1)))")); var stacks = disableSingleStepProfiling(); - assertEq(String(stacks), ",*,f*,Math." + name + "f*,f*,*,"); + assertEqualStacks(stacks, ",>,f>,Math." + name + "f>,f>,>,"); } for (name of ['ceil', 'floor']) testBuiltinF2F(name); @@ -71,7 +82,7 @@ function testBuiltinDD2D(name) { enableSingleStepProfiling(); assertEq(f(.1, .2), eval("Math." + name + "(.1, .2)")); var stacks = disableSingleStepProfiling(); - assertEq(String(stacks), ",*,f*,Math." + name + "f*,f*,*,"); + assertEqualStacks(stacks, ",>,f>,Math." + name + "f>,f>,>,"); } for (name of ['atan2', 'pow']) testBuiltinDD2D(name); @@ -88,14 +99,14 @@ var f = asmLink(asmCompile('g','ffis', USE_ASM + "var ffi1=ffis.ffi1, ffi2=ffis. enableSingleStepProfiling(); assertEq(f(), 83); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f*,*f*,f*,*f*,f*,*,"); +assertEqualStacks(stacks, ",>,f>,,f>,,f>,>,"); // Ion FFI exit for (var i = 0; i < 20; i++) assertEq(f(), 83); enableSingleStepProfiling(); assertEq(f(), 83); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f*,*f*,f*,*f*,f*,*,"); +assertEqualStacks(stacks, ",>,f>,,f>,,f>,>,"); var ffi1 = function() { return 15 } var ffi2 = function() { return f2() + 17 } @@ -104,14 +115,14 @@ var {f1,f2} = asmLink(asmCompile('g','ffis', USE_ASM + "var ffi1=ffis.ffi1, ffi2 enableSingleStepProfiling(); assertEq(f1(), 32); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f1*,*f1*,**f1*,f2**f1*,*f2**f1*,f2**f1*,**f1*,*f1*,f1*,*,"); +assertEqualStacks(stacks, ",>,f1>,,>,f2>,,f2>,>,,f1>,>,"); // Ion FFI exit for (var i = 0; i < 20; i++) assertEq(f1(), 32); enableSingleStepProfiling(); assertEq(f1(), 32); var stacks = disableSingleStepProfiling(); -assertEq(String(stacks), ",*,f1*,*f1*,**f1*,f2**f1*,*f2**f1*,f2**f1*,**f1*,*f1*,f1*,*,"); +assertEqualStacks(stacks, ",>,f1>,,>,f2>,,f2>,>,,f1>,>,"); // This takes forever to run. // Stack-overflow exit test diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 07c48cfe651..709f82fbe2a 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -1018,6 +1018,10 @@ class MOZ_STACK_CLASS ModuleCompiler private: struct SlowFunction { + SlowFunction(PropertyName *name, unsigned ms, unsigned line, unsigned column) + : name(name), ms(ms), line(line), column(column) + {} + PropertyName *name; unsigned ms; unsigned line; @@ -1423,7 +1427,10 @@ class MOZ_STACK_CLASS ModuleCompiler bool finishGeneratingFunction(Func &func, CodeGenerator &codegen, const AsmJSFunctionLabels &labels) { - if (!module_->addFunctionCodeRange(func.name(), labels)) + uint32_t line, column; + tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &line, &column); + + if (!module_->addFunctionCodeRange(func.name(), line, labels)) return false; jit::IonScriptCounts *counts = codegen.extractScriptCounts(); @@ -1433,17 +1440,12 @@ class MOZ_STACK_CLASS ModuleCompiler } if (func.compileTime() >= 250) { - SlowFunction sf; - sf.name = func.name(); - sf.ms = func.compileTime(); - tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &sf.line, &sf.column); + SlowFunction sf(func.name(), func.compileTime(), line, column); if (!slowFunctions_.append(sf)) return false; } #if defined(MOZ_VTUNE) || defined(JS_ION_PERF) - uint32_t line, column; - tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &line, &column); unsigned begin = labels.begin.offset(); unsigned end = labels.end.offset(); if (!module_->addProfiledFunction(func.name(), begin, end, line, column)) diff --git a/js/src/jit/AsmJSFrameIterator.cpp b/js/src/jit/AsmJSFrameIterator.cpp index f73e9c0cf9f..5d8492d50e4 100644 --- a/js/src/jit/AsmJSFrameIterator.cpp +++ b/js/src/jit/AsmJSFrameIterator.cpp @@ -599,90 +599,50 @@ AsmJSProfilingFrameIterator::operator++() JS_ASSERT(!done()); } -AsmJSProfilingFrameIterator::Kind -AsmJSProfilingFrameIterator::kind() const -{ - JS_ASSERT(!done()); - - switch (AsmJSExit::ExtractReasonKind(exitReason_)) { - case AsmJSExit::Reason_None: - break; - case AsmJSExit::Reason_Interrupt: - case AsmJSExit::Reason_FFI: - return JS::ProfilingFrameIterator::AsmJSTrampoline; - case AsmJSExit::Reason_Builtin: - return JS::ProfilingFrameIterator::CppFunction; - } - - auto codeRange = reinterpret_cast(codeRange_); - switch (codeRange->kind()) { - case AsmJSModule::CodeRange::Function: - return JS::ProfilingFrameIterator::Function; - case AsmJSModule::CodeRange::Entry: - case AsmJSModule::CodeRange::FFI: - case AsmJSModule::CodeRange::Interrupt: - case AsmJSModule::CodeRange::Inline: - return JS::ProfilingFrameIterator::AsmJSTrampoline; - case AsmJSModule::CodeRange::Thunk: - return JS::ProfilingFrameIterator::CppFunction; - } - - MOZ_ASSUME_UNREACHABLE("Bad kind"); -} - -JSAtom * -AsmJSProfilingFrameIterator::functionDisplayAtom() const -{ - JS_ASSERT(kind() == JS::ProfilingFrameIterator::Function); - return reinterpret_cast(codeRange_)->functionName(*module_); -} - -const char * -AsmJSProfilingFrameIterator::functionFilename() const -{ - JS_ASSERT(kind() == JS::ProfilingFrameIterator::Function); - return module_->scriptSource()->filename(); -} - static const char * BuiltinToName(AsmJSExit::BuiltinKind builtin) { + // Note: this label is regexp-matched by + // browser/devtools/profiler/cleopatra/js/parserWorker.js. + switch (builtin) { - case AsmJSExit::Builtin_ToInt32: return "ToInt32"; + case AsmJSExit::Builtin_ToInt32: return "ToInt32 (in asm.js)"; #if defined(JS_CODEGEN_ARM) - case AsmJSExit::Builtin_IDivMod: return "software idivmod"; - case AsmJSExit::Builtin_UDivMod: return "software uidivmod"; + case AsmJSExit::Builtin_IDivMod: return "software idivmod (in asm.js)"; + case AsmJSExit::Builtin_UDivMod: return "software uidivmod (in asm.js)"; #endif - case AsmJSExit::Builtin_ModD: return "fmod"; - case AsmJSExit::Builtin_SinD: return "Math.sin"; - case AsmJSExit::Builtin_CosD: return "Math.cos"; - case AsmJSExit::Builtin_TanD: return "Math.tan"; - case AsmJSExit::Builtin_ASinD: return "Math.asin"; - case AsmJSExit::Builtin_ACosD: return "Math.acos"; - case AsmJSExit::Builtin_ATanD: return "Math.atan"; + case AsmJSExit::Builtin_ModD: return "fmod (in asm.js)"; + case AsmJSExit::Builtin_SinD: return "Math.sin (in asm.js)"; + case AsmJSExit::Builtin_CosD: return "Math.cos (in asm.js)"; + case AsmJSExit::Builtin_TanD: return "Math.tan (in asm.js)"; + case AsmJSExit::Builtin_ASinD: return "Math.asin (in asm.js)"; + case AsmJSExit::Builtin_ACosD: return "Math.acos (in asm.js)"; + case AsmJSExit::Builtin_ATanD: return "Math.atan (in asm.js)"; case AsmJSExit::Builtin_CeilD: - case AsmJSExit::Builtin_CeilF: return "Math.ceil"; + case AsmJSExit::Builtin_CeilF: return "Math.ceil (in asm.js)"; case AsmJSExit::Builtin_FloorD: - case AsmJSExit::Builtin_FloorF: return "Math.floor"; - case AsmJSExit::Builtin_ExpD: return "Math.exp"; - case AsmJSExit::Builtin_LogD: return "Math.log"; - case AsmJSExit::Builtin_PowD: return "Math.pow"; - case AsmJSExit::Builtin_ATan2D: return "Math.atan2"; + case AsmJSExit::Builtin_FloorF: return "Math.floor (in asm.js)"; + case AsmJSExit::Builtin_ExpD: return "Math.exp (in asm.js)"; + case AsmJSExit::Builtin_LogD: return "Math.log (in asm.js)"; + case AsmJSExit::Builtin_PowD: return "Math.pow (in asm.js)"; + case AsmJSExit::Builtin_ATan2D: return "Math.atan2 (in asm.js)"; case AsmJSExit::Builtin_Limit: break; } MOZ_ASSUME_UNREACHABLE("Bad builtin kind"); } const char * -AsmJSProfilingFrameIterator::nonFunctionDescription() const +AsmJSProfilingFrameIterator::label() const { JS_ASSERT(!done()); - JS_ASSERT(kind() != JS::ProfilingFrameIterator::Function); + + // Note: this label is regexp-matched by + // browser/devtools/profiler/cleopatra/js/parserWorker.js. // Use the same string for both time inside and under so that the two // entries will be coalesced by the profiler. - const char *ffiDescription = "asm.js FFI trampoline"; - const char *interruptDescription = "asm.js slow script interrupt"; + const char *ffiDescription = "FFI trampoline (in asm.js)"; + const char *interruptDescription = "slow script interrupt trampoline (in asm.js)"; switch (AsmJSExit::ExtractReasonKind(exitReason_)) { case AsmJSExit::Reason_None: @@ -697,11 +657,11 @@ AsmJSProfilingFrameIterator::nonFunctionDescription() const auto codeRange = reinterpret_cast(codeRange_); switch (codeRange->kind()) { - case AsmJSModule::CodeRange::Function: MOZ_ASSUME_UNREACHABLE("non-functions only"); - case AsmJSModule::CodeRange::Entry: return "asm.js entry trampoline"; + case AsmJSModule::CodeRange::Function: return codeRange->functionProfilingLabel(*module_); + case AsmJSModule::CodeRange::Entry: return "entry trampoline (in asm.js)"; case AsmJSModule::CodeRange::FFI: return ffiDescription; case AsmJSModule::CodeRange::Interrupt: return interruptDescription; - case AsmJSModule::CodeRange::Inline: return "asm.js inline stub"; + case AsmJSModule::CodeRange::Inline: return "inline stub (in asm.js)"; case AsmJSModule::CodeRange::Thunk: return BuiltinToName(codeRange->thunkTarget()); } diff --git a/js/src/jit/AsmJSFrameIterator.h b/js/src/jit/AsmJSFrameIterator.h index a46d71f652d..1dcf3f284d7 100644 --- a/js/src/jit/AsmJSFrameIterator.h +++ b/js/src/jit/AsmJSFrameIterator.h @@ -133,15 +133,7 @@ class AsmJSProfilingFrameIterator bool done() const { return !codeRange_; } void *stackAddress() const { JS_ASSERT(!done()); return stackAddress_; } - - typedef JS::ProfilingFrameIterator::Kind Kind; - Kind kind() const; - - JSAtom *functionDisplayAtom() const; - const char *functionFilename() const; - unsigned functionLine() const; - - const char *nonFunctionDescription() const; + const char *label() const; }; /******************************************************************************/ diff --git a/js/src/jit/AsmJSModule.cpp b/js/src/jit/AsmJSModule.cpp index 461b025a28f..ba6bb99e049 100644 --- a/js/src/jit/AsmJSModule.cpp +++ b/js/src/jit/AsmJSModule.cpp @@ -1173,8 +1173,10 @@ AsmJSModule::ExportedFunction::clone(ExclusiveContext *cx, ExportedFunction *out return true; } -AsmJSModule::CodeRange::CodeRange(uint32_t nameIndex, const AsmJSFunctionLabels &l) +AsmJSModule::CodeRange::CodeRange(uint32_t nameIndex, uint32_t lineNumber, + const AsmJSFunctionLabels &l) : nameIndex_(nameIndex), + lineNumber_(lineNumber), begin_(l.begin.offset()), profilingReturn_(l.profilingReturn.offset()), end_(l.end.offset()) @@ -1535,6 +1537,29 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext *cx) if (profilingEnabled_ == enabled) return; + // When enabled, generate profiling labels for every name in names_ that is + // the name of some Function CodeRange. This involves malloc() so do it now + // since, once we start sampling, we'll be in a signal-handing context where + // we cannot malloc. + if (enabled) { + profilingLabels_.resize(names_.length()); + const char *filename = scriptSource_->filename(); + JS::AutoCheckCannotGC nogc; + for (size_t i = 0; i < codeRanges_.length(); i++) { + CodeRange &cr = codeRanges_[i]; + if (!cr.isFunction()) + continue; + unsigned lineno = cr.functionLineNumber(); + PropertyName *name = names_[cr.functionNameIndex()].name(); + profilingLabels_[cr.functionNameIndex()].reset( + name->hasLatin1Chars() + ? JS_smprintf("%s (%s:%u)", name->latin1Chars(nogc), filename, lineno) + : JS_smprintf("%hs (%s:%u)", name->twoByteChars(nogc), filename, lineno)); + } + } else { + profilingLabels_.clear(); + } + // Conservatively flush the icache for the entire module. AutoFlushICache afc("AsmJSModule::setProfilingEnabled"); setAutoFlushICacheRange(); diff --git a/js/src/jit/AsmJSModule.h b/js/src/jit/AsmJSModule.h index c4de480eb57..a0168f7c90d 100644 --- a/js/src/jit/AsmJSModule.h +++ b/js/src/jit/AsmJSModule.h @@ -335,6 +335,7 @@ class AsmJSModule class CodeRange { uint32_t nameIndex_; + uint32_t lineNumber_; uint32_t begin_; uint32_t profilingReturn_; uint32_t end_; @@ -358,7 +359,7 @@ class AsmJSModule enum Kind { Function, Entry, FFI, Interrupt, Thunk, Inline }; CodeRange() {} - CodeRange(uint32_t nameIndex, const AsmJSFunctionLabels &l); + CodeRange(uint32_t nameIndex, uint32_t lineNumber, const AsmJSFunctionLabels &l); CodeRange(Kind kind, uint32_t begin, uint32_t end); CodeRange(Kind kind, uint32_t begin, uint32_t profilingReturn, uint32_t end); CodeRange(AsmJSExit::BuiltinKind builtin, uint32_t begin, uint32_t pret, uint32_t end); @@ -393,10 +394,22 @@ class AsmJSModule JS_ASSERT(isFunction() || isFFI() || isInterrupt() || isThunk()); return profilingReturn_; } + uint32_t functionNameIndex() const { + JS_ASSERT(isFunction()); + return nameIndex_; + } PropertyName *functionName(const AsmJSModule &module) const { JS_ASSERT(isFunction()); return module.names_[nameIndex_].name(); } + const char *functionProfilingLabel(const AsmJSModule &module) const { + JS_ASSERT(isFunction()); + return module.profilingLabels_[nameIndex_].get(); + } + uint32_t functionLineNumber() const { + JS_ASSERT(isFunction()); + return lineNumber_; + } AsmJSExit::BuiltinKind thunkTarget() const { JS_ASSERT(isThunk()); return AsmJSExit::BuiltinKind(u.thunk.target_); @@ -430,6 +443,8 @@ class AsmJSModule bool clone(ExclusiveContext *cx, Name *out) const; }; + typedef mozilla::UniquePtr ProfilingLabel; + #if defined(MOZ_VTUNE) || defined(JS_ION_PERF) // Function information to add to the VTune JIT profiler following linking. struct ProfiledFunction @@ -603,6 +618,7 @@ class AsmJSModule Vector funcPtrTables_; Vector builtinThunkOffsets_; Vector names_; + Vector profilingLabels_; Vector heapAccesses_; Vector functionCounts_; #if defined(MOZ_VTUNE) || defined(JS_ION_PERF) @@ -801,13 +817,15 @@ class AsmJSModule if (len > pod.minHeapLength_) pod.minHeapLength_ = len; } - bool addFunctionCodeRange(PropertyName *name, const AsmJSFunctionLabels &labels) { + bool addFunctionCodeRange(PropertyName *name, uint32_t lineNumber, + const AsmJSFunctionLabels &labels) + { JS_ASSERT(!isFinished()); JS_ASSERT(name->isTenured()); if (names_.length() >= UINT32_MAX) return false; uint32_t nameIndex = names_.length(); - return names_.append(name) && codeRanges_.append(CodeRange(nameIndex, labels)); + return names_.append(name) && codeRanges_.append(CodeRange(nameIndex, lineNumber, labels)); } bool addEntryCodeRange(uint32_t begin, uint32_t end) { return codeRanges_.append(CodeRange(CodeRange::Entry, begin, end)); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index dccdf4226df..b7b71d1c354 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4273,26 +4273,8 @@ SingleStepCallback(void *arg, jit::Simulator *sim, void *pc) JS_ASSERT(i.stackAddress() != nullptr); JS_ASSERT(lastStackAddress <= i.stackAddress()); lastStackAddress = i.stackAddress(); - switch (i.kind()) { - case JS::ProfilingFrameIterator::Function: { - JS::AutoCheckCannotGC nogc; - JSAtom *atom = i.functionDisplayAtom(); - if (atom->hasLatin1Chars()) - stack.append(atom->latin1Chars(nogc), atom->length()); - else - stack.append(atom->twoByteChars(nogc), atom->length()); - break; - } - case JS::ProfilingFrameIterator::AsmJSTrampoline: { - stack.append('*'); - break; - } - case JS::ProfilingFrameIterator::CppFunction: { - const char *desc = i.nonFunctionDescription(); - stack.append(desc, strlen(desc)); - break; - } - } + const char *label = i.label(); + stack.append(label, strlen(label)); } // Only append the stack if it differs from the last stack. diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 2e6a53ffec2..dd260f856bc 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1842,44 +1842,11 @@ JS::ProfilingFrameIterator::stackAddress() const #endif } -JS::ProfilingFrameIterator::Kind -JS::ProfilingFrameIterator::kind() const -{ -#ifdef JS_ION - return iter().kind(); -#else - MOZ_CRASH("Shouldn't have any frames"); -#endif -} - -JSAtom * -JS::ProfilingFrameIterator::functionDisplayAtom() const -{ -#ifdef JS_ION - JS_ASSERT(kind() == Function); - return iter().functionDisplayAtom(); -#else - MOZ_CRASH("Shouldn't have any frames"); -#endif -} - const char * -JS::ProfilingFrameIterator::functionFilename() const +JS::ProfilingFrameIterator::label() const { #ifdef JS_ION - JS_ASSERT(kind() == Function); - return iter().functionFilename(); -#else - MOZ_CRASH("Shouldn't have any frames"); -#endif -} - -const char * -JS::ProfilingFrameIterator::nonFunctionDescription() const -{ -#ifdef JS_ION - JS_ASSERT(kind() != Function); - return iter().nonFunctionDescription(); + return iter().label(); #else MOZ_CRASH("Shouldn't have any frames"); #endif