Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (137178 => 137179)
--- trunk/Source/_javascript_Core/ChangeLog 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-12-10 18:38:15 UTC (rev 137179)
@@ -1,3 +1,28 @@
+2012-12-10 Filip Pizlo <[email protected]>
+
+ JSC profiling and debug dump code should use inferred names when possible
+ https://bugs.webkit.org/show_bug.cgi?id=104519
+
+ Reviewed by Oliver Hunt.
+
+ This does as advertised: the profiler now knows the inferred name of all code blocks,
+ and all uses of CodeBlock::dump() dump it along with the hash.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::inferredName):
+ (JSC::CodeBlock::dumpAssumingJITType):
+ * bytecode/CodeBlock.h:
+ * profiler/ProfilerBytecodes.cpp:
+ (JSC::Profiler::Bytecodes::Bytecodes):
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerBytecodes.h:
+ (JSC::Profiler::Bytecodes::inferredName):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::addBytecodes):
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * profiler/ProfilerDatabase.h:
+ * runtime/CommonIdentifiers.h:
+
2012-12-09 Filip Pizlo <[email protected]>
Profiler should say things about OSR exits
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (137178 => 137179)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-12-10 18:38:15 UTC (rev 137179)
@@ -64,6 +64,21 @@
using namespace DFG;
#endif
+String CodeBlock::inferredName() const
+{
+ switch (codeType()) {
+ case GlobalCode:
+ return "<global>";
+ case EvalCode:
+ return "<eval>";
+ case FunctionCode:
+ return jsCast<FunctionExecutable*>(ownerExecutable())->unlinkedExecutable()->inferredName().string();
+ default:
+ CRASH();
+ return String();
+ }
+}
+
CodeBlockHash CodeBlock::hash() const
{
return CodeBlockHash(ownerExecutable()->source(), specializationKind());
@@ -95,7 +110,7 @@
void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
{
- out.print("#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
+ out.print(inferredName(), "#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
if (codeType() == FunctionCode)
out.print(specializationKind());
out.print("]");
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (137178 => 137179)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-12-10 18:38:15 UTC (rev 137179)
@@ -131,7 +131,8 @@
JS_EXPORT_PRIVATE virtual ~CodeBlock();
UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
-
+
+ String inferredName() const;
CodeBlockHash hash() const;
String sourceCodeForTools() const; // Not quite the actual source we parsed; this will do things like prefix the source for a function with a reified signature.
String sourceCodeOnOneLine() const; // As sourceCodeForTools(), but replaces all whitespace runs with a single space.
Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp (137178 => 137179)
--- trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp 2012-12-10 18:38:15 UTC (rev 137179)
@@ -31,8 +31,10 @@
namespace JSC { namespace Profiler {
-Bytecodes::Bytecodes(size_t id, const String& sourceCode, CodeBlockHash hash)
+Bytecodes::Bytecodes(
+ size_t id, const String& inferredName, const String& sourceCode, CodeBlockHash hash)
: m_id(id)
+ , m_inferredName(inferredName)
, m_sourceCode(sourceCode)
, m_hash(hash)
{
@@ -60,6 +62,7 @@
JSObject* result = constructEmptyObject(exec);
result->putDirect(exec->globalData(), exec->propertyNames().bytecodesID, jsNumber(m_id));
+ result->putDirect(exec->globalData(), exec->propertyNames().inferredName, jsString(exec, m_inferredName));
result->putDirect(exec->globalData(), exec->propertyNames().sourceCode, jsString(exec, m_sourceCode));
result->putDirect(exec->globalData(), exec->propertyNames().hash, jsString(exec, String::fromUTF8(toCString(m_hash))));
Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h (137178 => 137179)
--- trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h 2012-12-10 18:38:15 UTC (rev 137179)
@@ -36,12 +36,13 @@
class Bytecodes {
public:
- Bytecodes(size_t id, const String& sourceCode, CodeBlockHash);
+ Bytecodes(size_t id, const String& inferredName, const String& sourceCode, CodeBlockHash);
~Bytecodes();
void append(const Bytecode& bytecode) { m_bytecode.append(bytecode); }
size_t id() const { return m_id; }
+ const String& inferredName() const { return m_inferredName; }
const String& sourceCode() const { return m_sourceCode; }
CodeBlockHash hash() const { return m_hash; }
@@ -58,6 +59,7 @@
private:
size_t m_id;
+ String m_inferredName;
String m_sourceCode;
CodeBlockHash m_hash;
Vector<Bytecode> m_bytecode;
Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (137178 => 137179)
--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2012-12-10 18:38:15 UTC (rev 137179)
@@ -41,9 +41,10 @@
{
}
-Bytecodes* Database::addBytecodes(CodeBlockHash hash, const String& sourceCode)
+Bytecodes* Database::addBytecodes(
+ CodeBlockHash hash, const String& inferredName, const String& sourceCode)
{
- m_bytecodes.append(Bytecodes(m_bytecodes.size(), sourceCode, hash));
+ m_bytecodes.append(Bytecodes(m_bytecodes.size(), inferredName, sourceCode, hash));
return &m_bytecodes.last();
}
@@ -57,7 +58,8 @@
if (iter != m_bytecodesMap.end())
return iter->value;
- Bytecodes* result = addBytecodes(codeBlock->hash(), codeBlock->sourceCodeForTools());
+ Bytecodes* result = addBytecodes(
+ codeBlock->hash(), codeBlock->inferredName(), codeBlock->sourceCodeForTools());
for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
out.reset();
Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h (137178 => 137179)
--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h 2012-12-10 18:38:15 UTC (rev 137179)
@@ -66,7 +66,7 @@
JS_EXPORT_PRIVATE bool save(const char* filename) const;
private:
- Bytecodes* addBytecodes(CodeBlockHash, const String& sourceCode);
+ Bytecodes* addBytecodes(CodeBlockHash, const String& inferredName, const String& sourceCode);
JSGlobalData& m_globalData;
SegmentedVector<Bytecodes> m_bytecodes;
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (137178 => 137179)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2012-12-10 18:38:15 UTC (rev 137179)
@@ -60,6 +60,7 @@
macro(id) \
macro(ignoreCase) \
macro(index) \
+ macro(inferredName) \
macro(input) \
macro(isArray) \
macro(isPrototypeOf) \
Modified: trunk/Tools/ChangeLog (137178 => 137179)
--- trunk/Tools/ChangeLog 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Tools/ChangeLog 2012-12-10 18:38:15 UTC (rev 137179)
@@ -1,3 +1,17 @@
+2012-12-10 Filip Pizlo <[email protected]>
+
+ JSC profiling and debug dump code should use inferred names when possible
+ https://bugs.webkit.org/show_bug.cgi?id=104519
+
+ Reviewed by Oliver Hunt.
+
+ The format I'm using for referring to a code block is now name#hash. For example,
+ v8-crypto has something called bnpSquareTo#B5QFbU. The profiler allows you to use
+ either the hash, the inferred name, or the combined hash and full name when referring
+ to blocks.
+
+ * Scripts/display-profiler-output:
+
2012-12-09 Filip Pizlo <[email protected]>
Profiler should say things about OSR exits
Modified: trunk/Tools/Scripts/display-profiler-output (137178 => 137179)
--- trunk/Tools/Scripts/display-profiler-output 2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Tools/Scripts/display-profiler-output 2012-12-10 18:38:15 UTC (rev 137179)
@@ -133,10 +133,11 @@
end
class Bytecodes
- attr_accessor :codeHash, :source, :machineInlineSites, :compilations
+ attr_accessor :codeHash, :inferredName, :source, :machineInlineSites, :compilations
def initialize(json)
@codeHash = json["hash"].to_s
+ @inferredName = json["inferredName"].to_s
@source = json["sourceCode"].to_s
@bytecode = {}
json["bytecode"].each {
@@ -148,6 +149,28 @@
@compilations = []
end
+ def name(limit)
+ if to_s.size > limit
+ "\##{@codeHash}"
+ else
+ to_s
+ end
+ end
+
+ def to_s
+ "#{@inferredName}\##{@codeHash}"
+ end
+
+ def matches(pattern)
+ if pattern =~ /^#/
+ $~.post_match == @codeHash
+ elsif pattern =~ /#/
+ pattern == to_s
+ else
+ pattern == @inferredName or pattern == @codeHash
+ end
+ end
+
def each
@bytecode.values.sort{|a, b| a.bytecodeIndex <=> b.bytecodeIndex}.each {
| value |
@@ -318,7 +341,7 @@
end
def to_s
- "\##{bytecode.codeHash}-#{compilationIndex}-#{engine}"
+ "#{bytecode}-#{compilationIndex}-#{engine}"
end
end
@@ -388,17 +411,9 @@
end
def mayBeHash(hash)
- hash =~ /^#/ or hash.size == 6
+ hash =~ /#/ or hash.size == 6
end
-def getHash(hash)
- if hash =~ /^#/
- $~.post_match
- else
- hash
- end
-end
-
def sourceOnOneLine(source, limit)
source.gsub(/\s+/, ' ')[0...limit]
end
@@ -410,7 +425,7 @@
def summary(mode)
remaining = screenWidth
- hashCols = 11
+ hashCols = 20
remaining -= hashCols + 1
countCols = 9 * $engines.size
@@ -460,7 +475,7 @@
b.totalMaxTopExecutionCount <=> a.totalMaxTopExecutionCount
}.each {
| bytecode |
- print(center("#" + bytecode.codeHash, hashCols) + " " +
+ print(center(bytecode.name(hashCols), hashCols) + " " +
center($engines.map {
| engine |
bytecode.maxTopExecutionCount(engine).to_s
@@ -507,7 +522,7 @@
end
$bytecodes.each {
| bytecode |
- if bytecode.codeHash == args[0]
+ if bytecode.matches(args[0])
puts bytecode.source
end
}
@@ -526,12 +541,12 @@
pad += 1
end
- puts(center("Source Counts", countCols) + " " + center("Machine Counts", machineCols) +
- (" " * pad) + center("Bytecode for #{hash}", screenWidth - pad - countCols - 1 - machineCols))
- puts(center("Base/DFG", countCols) + " " + center("Base/DFG", countCols))
$bytecodes.each {
| bytecodes |
- next if bytecodes.codeHash != hash
+ next unless bytecodes.matches(hash)
+ puts(center("Source Counts", countCols) + " " + center("Machine Counts", machineCols) +
+ (" " * pad) + center("Bytecode for #{bytecodes}", screenWidth - pad - countCols - 1 - machineCols))
+ puts(center("Base/DFG", countCols) + " " + center("Base/DFG", countCols))
bytecodes.each {
| bytecode |
if bytecode.shouldHaveCounts?
@@ -565,7 +580,7 @@
$bytecodes.each {
| bytecodes |
- next if bytecodes.codeHash != hash
+ next unless bytecodes.matches(hash)
# FIXME: print something useful to say more about which code block this is.
@@ -601,7 +616,7 @@
def originToPrintStack(origin)
(0...(origin.size - 1)).map {
| index |
- "bc\##{origin[index].bytecodeIndex} --> \##{origin[index + 1].bytecodes.codeHash}"
+ "bc\##{origin[index].bytecodeIndex} --> #{origin[index + 1].bytecodes}"
}
end
@@ -674,15 +689,13 @@
engine = trueEngine
end
- hash = getHash(hash)
-
actualCountCols = 13
sourceCountCols = 10 * $engines.size
first = true
$compilations.each {
| compilation |
- next if compilation.bytecode.codeHash != hash
+ next unless compilation.bytecode.matches(hash)
next if engine and compilation.engine != engine
next if compilationIndex and compilation.compilationIndex != compilationIndex