Commit 237b1464 authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: DFG IR dumps should be easier to read

https://bugs.webkit.org/show_bug.cgi?id=119050

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Added a DumpContext that includes support for printing an endnote
that describes all structures in full, while the main flow of the
dump just uses made-up names for the structures. This is helpful
since Structure::dump() may print a lot. The stuff it prints is
useful, but if it's all inline with the surrounding thing you're
dumping (often, a node in the DFG), then you get a ridiculously
long print-out. All classes that dump structures (including
Structure itself) now have dumpInContext() methods that use
inContext() for dumping anything that might transitively print a
structure. If Structure::dumpInContext() is called with a NULL
context, it just uses dump() like before. Hence you don't have to
know anything about DumpContext unless you want to.

inContext(*structure, context) dumps something like %B4:Array,
and the endnote will have something like:

    %B4:Array    = 0x10e91a180:[Array, {Edge:100, Normal:101, Line:102, NumPx:103, LastPx:104}, ArrayWithContiguous, Proto:0x10e99ffe0]

where B4 is the inferred name that StringHashDumpContext came up
with.

Also shortened a bunch of other dumps, removing information that
isn't so important.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/ArrayProfile.cpp:
(JSC::dumpArrayModes):
* bytecode/CodeBlockHash.cpp:
(JSC):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::dump):
* bytecode/CodeOrigin.cpp:
(JSC::CodeOrigin::dumpInContext):
(JSC):
(JSC::InlineCallFrame::dumpInContext):
(JSC::InlineCallFrame::dump):
* bytecode/CodeOrigin.h:
(CodeOrigin):
(InlineCallFrame):
* bytecode/Operands.h:
(JSC::OperandValueTraits::isEmptyForDump):
(Operands):
(JSC::Operands::dump):
(JSC):
* bytecode/OperandsInlines.h: Added.
(JSC):
(JSC::::dumpInContext):
* bytecode/StructureSet.h:
(JSC::StructureSet::dumpInContext):
(JSC::StructureSet::dump):
(StructureSet):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::dump):
(DFG):
(JSC::DFG::AbstractValue::dumpInContext):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::operator!):
(AbstractValue):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::performBlockCFA):
* dfg/DFGCommon.cpp:
* dfg/DFGCommon.h:
(JSC::DFG::NodePointerTraits::isEmptyForDump):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::createDumpList):
* dfg/DFGDisassembler.h:
(Disassembler):
* dfg/DFGFlushFormat.h:
(WTF::inContext):
(WTF):
* dfg/DFGFlushLivenessAnalysisPhase.cpp:
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dumpCodeOrigin):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dumpBlockHeader):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGLazyJSValue.cpp:
(JSC::DFG::LazyJSValue::dumpInContext):
(JSC::DFG::LazyJSValue::dump):
(DFG):
* dfg/DFGLazyJSValue.h:
(LazyJSValue):
* dfg/DFGNode.h:
(JSC::DFG::nodeMapDump):
(WTF::inContext):
(WTF):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::dumpInContext):
(JSC::DFG::StructureAbstractValue::dump):
(StructureAbstractValue):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
(JSC::FTL::ExitValue::dump):
(FTL):
* ftl/FTLExitValue.h:
(ExitValue):
* ftl/FTLLowerDFGToLLVM.cpp:
* ftl/FTLValueSource.cpp:
(JSC::FTL::ValueSource::dumpInContext):
(FTL):
* ftl/FTLValueSource.h:
(ValueSource):
* runtime/DumpContext.cpp: Added.
(JSC):
(JSC::DumpContext::DumpContext):
(JSC::DumpContext::~DumpContext):
(JSC::DumpContext::isEmpty):
(JSC::DumpContext::dump):
* runtime/DumpContext.h: Added.
(JSC):
(DumpContext):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
(JSC):
(JSC::JSValue::dumpInContext):
* runtime/JSCJSValue.h:
(JSC):
(JSValue):
* runtime/Structure.cpp:
(JSC::Structure::dumpInContext):
(JSC):
(JSC::Structure::dumpBrief):
(JSC::Structure::dumpContextHeader):
* runtime/Structure.h:
(JSC):
(Structure):

Source/WTF:

Reviewed by Mark Hahnenberg.

Added support for dumping values within a context. By default, if you say
print(inContext(value, context)) it calls value.dumpInContext(out, context)
instead of value.dump(out).

Hoisted the support for six-character hashes out of JSC::CodeBlockHash into
WTF, in the form of SixCharacterHash.h.

Added a helper for creating dump contexts where the inContext() dump will
just use a short string hash to "name" the object being dumped, and then
will print out the full dumps in an endnote to your dump.

Added support for using CString as a hashtable key.

* WTF.xcodeproj/project.pbxproj:
* wtf/PrintStream.h:
(WTF):
(ValueInContext):
(WTF::ValueInContext::ValueInContext):
(WTF::ValueInContext::dump):
(WTF::inContext):
* wtf/SixCharacterHash.cpp: Added.
(WTF):
(WTF::sixCharacterHashStringToInteger):
(WTF::integerToSixCharacterHashString):
* wtf/SixCharacterHash.h: Added.
(WTF):
* wtf/StringHashDumpContext.h: Added.
(WTF):
(StringHashDumpContext):
(WTF::StringHashDumpContext::StringHashDumpContext):
(WTF::StringHashDumpContext::getID):
(WTF::StringHashDumpContext::dumpBrief):
(WTF::StringHashDumpContext::brief):
(WTF::StringHashDumpContext::isEmpty):
(WTF::StringHashDumpContext::dump):
* wtf/text/CString.cpp:
(WTF::CString::hash):
(WTF):
(WTF::operator<):
(WTF::CStringHash::equal):
* wtf/text/CString.h:
(WTF::CString::CString):
(CString):
(WTF::CString::isHashTableDeletedValue):
(WTF):
(WTF::CStringHash::hash):
(CStringHash):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153296 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e17632e6
2013-07-24 Filip Pizlo <fpizlo@apple.com>
fourthTier: DFG IR dumps should be easier to read
https://bugs.webkit.org/show_bug.cgi?id=119050
Reviewed by Mark Hahnenberg.
Added a DumpContext that includes support for printing an endnote
that describes all structures in full, while the main flow of the
dump just uses made-up names for the structures. This is helpful
since Structure::dump() may print a lot. The stuff it prints is
useful, but if it's all inline with the surrounding thing you're
dumping (often, a node in the DFG), then you get a ridiculously
long print-out. All classes that dump structures (including
Structure itself) now have dumpInContext() methods that use
inContext() for dumping anything that might transitively print a
structure. If Structure::dumpInContext() is called with a NULL
context, it just uses dump() like before. Hence you don't have to
know anything about DumpContext unless you want to.
inContext(*structure, context) dumps something like %B4:Array,
and the endnote will have something like:
%B4:Array = 0x10e91a180:[Array, {Edge:100, Normal:101, Line:102, NumPx:103, LastPx:104}, ArrayWithContiguous, Proto:0x10e99ffe0]
where B4 is the inferred name that StringHashDumpContext came up
with.
Also shortened a bunch of other dumps, removing information that
isn't so important.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/ArrayProfile.cpp:
(JSC::dumpArrayModes):
* bytecode/CodeBlockHash.cpp:
(JSC):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::dump):
* bytecode/CodeOrigin.cpp:
(JSC::CodeOrigin::dumpInContext):
(JSC):
(JSC::InlineCallFrame::dumpInContext):
(JSC::InlineCallFrame::dump):
* bytecode/CodeOrigin.h:
(CodeOrigin):
(InlineCallFrame):
* bytecode/Operands.h:
(JSC::OperandValueTraits::isEmptyForDump):
(Operands):
(JSC::Operands::dump):
(JSC):
* bytecode/OperandsInlines.h: Added.
(JSC):
(JSC::::dumpInContext):
* bytecode/StructureSet.h:
(JSC::StructureSet::dumpInContext):
(JSC::StructureSet::dump):
(StructureSet):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::dump):
(DFG):
(JSC::DFG::AbstractValue::dumpInContext):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::operator!):
(AbstractValue):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::performBlockCFA):
* dfg/DFGCommon.cpp:
* dfg/DFGCommon.h:
(JSC::DFG::NodePointerTraits::isEmptyForDump):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::createDumpList):
* dfg/DFGDisassembler.h:
(Disassembler):
* dfg/DFGFlushFormat.h:
(WTF::inContext):
(WTF):
* dfg/DFGFlushLivenessAnalysisPhase.cpp:
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dumpCodeOrigin):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dumpBlockHeader):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGLazyJSValue.cpp:
(JSC::DFG::LazyJSValue::dumpInContext):
(JSC::DFG::LazyJSValue::dump):
(DFG):
* dfg/DFGLazyJSValue.h:
(LazyJSValue):
* dfg/DFGNode.h:
(JSC::DFG::nodeMapDump):
(WTF::inContext):
(WTF):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::dumpInContext):
(JSC::DFG::StructureAbstractValue::dump):
(StructureAbstractValue):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
(JSC::FTL::ExitValue::dump):
(FTL):
* ftl/FTLExitValue.h:
(ExitValue):
* ftl/FTLLowerDFGToLLVM.cpp:
* ftl/FTLValueSource.cpp:
(JSC::FTL::ValueSource::dumpInContext):
(FTL):
* ftl/FTLValueSource.h:
(ValueSource):
* runtime/DumpContext.cpp: Added.
(JSC):
(JSC::DumpContext::DumpContext):
(JSC::DumpContext::~DumpContext):
(JSC::DumpContext::isEmpty):
(JSC::DumpContext::dump):
* runtime/DumpContext.h: Added.
(JSC):
(DumpContext):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
(JSC):
(JSC::JSValue::dumpInContext):
* runtime/JSCJSValue.h:
(JSC):
(JSValue):
* runtime/Structure.cpp:
(JSC::Structure::dumpInContext):
(JSC):
(JSC::Structure::dumpBrief):
(JSC::Structure::dumpContextHeader):
* runtime/Structure.h:
(JSC):
(Structure):
2013-07-22 Filip Pizlo <fpizlo@apple.com>
fourthTier: DFG should do a high-level LICM before going to FTL
......
......@@ -735,6 +735,9 @@
A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1712B3A11C7B212007A5315 /* RegExpCache.cpp */; };
A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B4011C7B235007A5315 /* RegExpKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A70447E917A0BD4600F5898E /* OperandsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
A70447ED17A0BD7000F5898E /* DumpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A70447EB17A0BD7000F5898E /* DumpContext.cpp */; };
A70447EE17A0BD7000F5898E /* DumpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A70447EC17A0BD7000F5898E /* DumpContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
A704D90317A0BAA8006BA554 /* DFGAbstractInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = A704D8FE17A0BAA8006BA554 /* DFGAbstractInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
A704D90417A0BAA8006BA554 /* DFGAbstractInterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A704D8FF17A0BAA8006BA554 /* DFGAbstractInterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
A704D90517A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */; };
......@@ -1814,6 +1817,9 @@
A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; };
A70447E917A0BD4600F5898E /* OperandsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OperandsInlines.h; sourceTree = "<group>"; };
A70447EB17A0BD7000F5898E /* DumpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DumpContext.cpp; sourceTree = "<group>"; };
A70447EC17A0BD7000F5898E /* DumpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumpContext.h; sourceTree = "<group>"; };
A704D8FE17A0BAA8006BA554 /* DFGAbstractInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractInterpreter.h; path = dfg/DFGAbstractInterpreter.h; sourceTree = "<group>"; };
A704D8FF17A0BAA8006BA554 /* DFGAbstractInterpreterInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractInterpreterInlines.h; path = dfg/DFGAbstractInterpreterInlines.h; sourceTree = "<group>"; };
A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInPlaceAbstractState.cpp; path = dfg/DFGInPlaceAbstractState.cpp; sourceTree = "<group>"; };
......@@ -2197,9 +2203,9 @@
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
932F5BE10822A1C700736975 /* jsc */,
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
141211200A48793C00480255 /* minidom */,
14BD59BF0A3E8F9000BAF59C /* testapi */,
6511230514046A4C002B101D /* testRegExp */,
......@@ -2833,6 +2839,8 @@
14A1563010966365006FA260 /* DateInstanceCache.h */,
BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
BCD203480E17135E002C7E82 /* DatePrototype.h */,
A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
A70447EC17A0BD7000F5898E /* DumpContext.h */,
BC337BEA0E1B00CB0076918A /* Error.cpp */,
BC3046060E1F497F003232CF /* Error.h */,
BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */,
......@@ -3403,6 +3411,7 @@
969A07940ED1D3AE00F1F681 /* Opcode.cpp */,
969A07950ED1D3AE00F1F681 /* Opcode.h */,
0F2BDC2B151FDE8B00CD8910 /* Operands.h */,
A70447E917A0BD4600F5898E /* OperandsInlines.h */,
0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */,
0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
......@@ -3647,6 +3656,7 @@
0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
0FDB2CE8174830A2007B3C1B /* DFGWorklist.h in Headers */,
0FF42731158EBD54004CB9FF /* Disassembler.h in Headers */,
A70447EE17A0BD7000F5898E /* DumpContext.h in Headers */,
BC3046070E1F497F003232CF /* Error.h in Headers */,
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
......@@ -3885,6 +3895,7 @@
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
0FE228ED1436AB2700196C48 /* Options.h in Headers */,
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
......@@ -4490,6 +4501,7 @@
0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
0FDB2CE7174830A2007B3C1B /* DFGWorklist.cpp in Sources */,
0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
A70447ED17A0BD7000F5898E /* DumpContext.cpp in Sources */,
147F39C7107EC37600427A48 /* Error.cpp in Sources */,
147F39C8107EC37600427A48 /* ErrorConstructor.cpp in Sources */,
147F39C9107EC37600427A48 /* ErrorInstance.cpp in Sources */,
......
......@@ -35,7 +35,7 @@ namespace JSC {
void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
{
if (!arrayModes) {
out.print("0:<empty>");
out.print("<empty>");
return;
}
......@@ -44,34 +44,33 @@ void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
return;
}
out.print(arrayModes, ":");
CommaPrinter comma("|");
if (arrayModes & asArrayModes(NonArray))
out.print("NonArray");
out.print(comma, "NonArray");
if (arrayModes & asArrayModes(NonArrayWithInt32))
out.print("NonArrayWithInt32");
out.print(comma, "NonArrayWithInt32");
if (arrayModes & asArrayModes(NonArrayWithDouble))
out.print("NonArrayWithDouble");
out.print(comma, "NonArrayWithDouble");
if (arrayModes & asArrayModes(NonArrayWithContiguous))
out.print("NonArrayWithContiguous");
out.print(comma, "NonArrayWithContiguous");
if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
out.print("NonArrayWithArrayStorage");
out.print(comma, "NonArrayWithArrayStorage");
if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
out.print("NonArrayWithSlowPutArrayStorage");
out.print(comma, "NonArrayWithSlowPutArrayStorage");
if (arrayModes & asArrayModes(ArrayClass))
out.print("ArrayClass");
out.print(comma, "ArrayClass");
if (arrayModes & asArrayModes(ArrayWithUndecided))
out.print("ArrayWithUndecided");
out.print(comma, "ArrayWithUndecided");
if (arrayModes & asArrayModes(ArrayWithInt32))
out.print("ArrayWithInt32");
out.print(comma, "ArrayWithInt32");
if (arrayModes & asArrayModes(ArrayWithDouble))
out.print("ArrayWithDouble");
out.print(comma, "ArrayWithDouble");
if (arrayModes & asArrayModes(ArrayWithContiguous))
out.print("ArrayWithContiguous");
out.print(comma, "ArrayWithContiguous");
if (arrayModes & asArrayModes(ArrayWithArrayStorage))
out.print("ArrayWithArrayStorage");
out.print(comma, "ArrayWithArrayStorage");
if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
out.print("ArrayWithSlowPutArrayStorage");
out.print(comma, "ArrayWithSlowPutArrayStorage");
}
void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock)
......
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
* Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -28,30 +28,13 @@
#include "SourceCode.h"
#include <wtf/SHA1.h>
#include <wtf/SixCharacterHash.h>
namespace JSC {
#define TABLE ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
CodeBlockHash::CodeBlockHash(const char* string)
: m_hash(0)
: m_hash(sixCharacterHashStringToInteger(string))
{
RELEASE_ASSERT(strlen(string) == 6);
for (unsigned i = 0; i < 6; ++i) {
m_hash *= 62;
unsigned c = string[i];
if (c >= 'A' && c <= 'Z') {
m_hash += c - 'A';
continue;
}
if (c >= 'a' && c <= 'z') {
m_hash += c - 'a' + 26;
continue;
}
ASSERT(c >= '0' && c <= '9');
m_hash += c - '0' + 26 * 2;
}
}
CodeBlockHash::CodeBlockHash(const SourceCode& sourceCode, CodeSpecializationKind kind)
......@@ -71,22 +54,14 @@ CodeBlockHash::CodeBlockHash(const SourceCode& sourceCode, CodeSpecializationKin
void CodeBlockHash::dump(PrintStream& out) const
{
ASSERT(strlen(TABLE) == 62);
char buffer[7];
unsigned accumulator = m_hash;
for (unsigned i = 6; i--;) {
buffer[i] = TABLE[accumulator % 62];
accumulator /= 62;
}
buffer[6] = 0;
FixedArray<char, 7> buffer = integerToSixCharacterHashString(m_hash);
#if !ASSERT_DISABLED
CodeBlockHash recompute(buffer);
CodeBlockHash recompute(buffer.data());
ASSERT(recompute == *this);
#endif // !ASSERT_DISABLED
out.print(buffer);
out.print(buffer.data());
}
} // namespace JSC
......
......@@ -74,6 +74,11 @@ void CodeOrigin::dump(PrintStream& out) const
}
}
void CodeOrigin::dumpInContext(PrintStream& out, DumpContext*) const
{
dump(out);
}
JSFunction* InlineCallFrame::calleeForCallFrame(ExecState* exec) const
{
if (!isClosureCall())
......@@ -103,11 +108,11 @@ void InlineCallFrame::dumpBriefFunctionInformation(PrintStream& out) const
out.print(inferredName(), "#", hash());
}
void InlineCallFrame::dump(PrintStream& out) const
void InlineCallFrame::dumpInContext(PrintStream& out, DumpContext* context) const
{
out.print(briefFunctionInformation(), ":<", RawPointer(executable.get()), ", bc#", caller.bytecodeIndex, ", ", specializationKind());
if (callee)
out.print(", known callee: ", JSValue(callee.get()));
out.print(", known callee: ", inContext(JSValue(callee.get()), context));
else
out.print(", closure call");
out.print(", numArgs+this = ", arguments.size());
......@@ -115,5 +120,10 @@ void InlineCallFrame::dump(PrintStream& out) const
out.print(">");
}
void InlineCallFrame::dump(PrintStream& out) const
{
dumpInContext(out, 0);
}
} // namespace JSC
......@@ -88,6 +88,7 @@ struct CodeOrigin {
Vector<CodeOrigin> inlineStack() const;
void dump(PrintStream&) const;
void dumpInContext(PrintStream&, DumpContext*) const;
};
struct InlineCallFrame {
......@@ -113,6 +114,7 @@ struct InlineCallFrame {
void dumpBriefFunctionInformation(PrintStream&) const;
void dump(PrintStream&) const;
void dumpInContext(PrintStream&, DumpContext*) const;
MAKE_PRINT_METHOD(InlineCallFrame, dumpBriefFunctionInformation, briefFunctionInformation);
};
......
/*
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -43,7 +43,7 @@ template<typename T> struct OperandValueTraits;
template<typename T>
struct OperandValueTraits {
static T defaultValue() { return T(); }
static void dump(const T& value, PrintStream& out) { out.print(value); }
static bool isEmptyForDump(const T& value) { return !value; }
};
enum OperandKind { ArgumentOperand, LocalOperand };
......@@ -230,37 +230,18 @@ public:
return m_arguments == other.m_arguments && m_locals == other.m_locals;
}
void dump(PrintStream& out) const;
void dumpInContext(PrintStream& out, DumpContext* context) const;
void dump(PrintStream& out) const
{
dumpInContext(out, 0);
}
private:
Vector<T, 8> m_arguments;
Vector<T, 16> m_locals;
};
template<typename T, typename Traits>
void dumpOperands(const Operands<T, Traits>& operands, PrintStream& out)
{
for (size_t argument = operands.numberOfArguments(); argument--;) {
if (argument != operands.numberOfArguments() - 1)
out.printf(" ");
out.print("arg", argument, ":");
Traits::dump(operands.argument(argument), out);
}
out.printf(" : ");
for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
if (local)
out.printf(" ");
out.print("r", local, ":");
Traits::dump(operands.local(local), out);
}
}
template<typename T, typename Traits>
inline void Operands<T, Traits>::dump(PrintStream& out) const
{
dumpOperands(*this, out);
}
} // namespace JSC
#endif // Operands_h
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OperandsInlines_h
#define OperandsInlines_h
#include "Operands.h"
#include <wtf/CommaPrinter.h>
namespace JSC {
template<typename T, typename Traits>
void Operands<T, Traits>::dumpInContext(PrintStream& out, DumpContext* context) const
{
CommaPrinter comma(" ");
for (size_t argumentIndex = numberOfArguments(); argumentIndex--;) {
if (Traits::isEmptyForDump(argument(argumentIndex)))
continue;
out.print(comma, "arg", argumentIndex, ":", inContext(argument(argumentIndex), context));
}
for (size_t localIndex = 0; localIndex < numberOfLocals(); ++localIndex) {
if (Traits::isEmptyForDump(local(localIndex)))
continue;
out.print(comma, "r", localIndex, ":", inContext(local(localIndex), context));
}
}
} // namespace JSC
#endif // OperandsInlines_h
......@@ -29,6 +29,7 @@
#include "ArrayProfile.h"
#include "SpeculatedType.h"
#include "Structure.h"
#include "DumpContext.h"
#include <stdio.h>
#include <wtf/CommaPrinter.h>
#include <wtf/Vector.h>
......@@ -162,15 +163,20 @@ public:
return true;
}
void dump(PrintStream& out) const
void dumpInContext(PrintStream& out, DumpContext* context) const
{
CommaPrinter comma;
out.print("[");
for (size_t i = 0; i < m_structures.size(); ++i)
out.print(comma, *m_structures[i]);
out.print(comma, inContext(*m_structures[i], context));
out.print("]");
}
void dump(PrintStream& out) const
{
dumpInContext(out, 0);
}
private:
friend class DFG::StructureAbstractValue;
......
......@@ -252,11 +252,20 @@ void AbstractValue::checkConsistency() const
void AbstractValue::dump(PrintStream& out) const
{
out.print(
"(", SpeculationDump(m_type), ", ", ArrayModesDump(m_arrayModes), ", ",
m_currentKnownStructure, ", ", m_futurePossibleStructure);
dumpInContext(out, 0);
}
void AbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const
{
out.print("(", SpeculationDump(m_type));
if (m_type & SpecCell) {
out.print(
", ", ArrayModesDump(m_arrayModes), ", ",
inContext(m_currentKnownStructure, context), ", ",
inContext(m_futurePossibleStructure, context));
}
if (!!m_value)
out.print(", ", m_value);
out.print(", ", inContext(m_value, context));
out.print(")");
}
......
......@@ -35,6 +35,7 @@
#include "DFGStructureAbstractValue.h"
#include "JSCell.h"
#include "SpeculatedType.h"
#include "DumpContext.h"
#include "StructureSet.h"
namespace JSC { namespace DFG {
......@@ -59,6 +60,7 @@ struct AbstractValue {
}
bool isClear() const { return m_type == SpecNone; }
bool operator!() const { return isClear(); }
void makeTop()
{
......@@ -251,6 +253,7 @@ struct AbstractValue {
void checkConsistency() const;
void dumpInContext(PrintStream&, DumpContext*) const;
void dump(PrintStream&) const;
// A great way to think about the difference between m_currentKnownStructure and
......
......@@ -33,6 +33,7 @@
#include "DFGInPlaceAbstractState.h"
#include "DFGPhase.h"
#include "DFGSafeToExecute.h"
#include "OperandsInlines.h"
#include "Operations.h"
namespace JSC { namespace DFG {
......@@ -91,11 +92,8 @@ private:
if (m_verbose)
dataLog(" Block ", *block, ":\n");
m_state.beginBasicBlock(block);
if (m_verbose) {
dataLogF(" head vars: ");
dumpOperands(block->valuesAtHead, WTF::dataFile());
dataLogF("\n");
}
if (m_verbose)
dataLog(" head vars: ", block->valuesAtHead, "\n");
for (unsigned i = 0; i < block->size(); ++i) {
if (m_verbose) {
Node* node = block->at(i);
......@@ -123,11 +121,8 @@ private:
}
m_changed |= m_state.endBasicBlock(MergeToSuccessors);
if (m_verbose) {
dataLogF(" tail vars: ");
dumpOperands(block->valuesAtTail, WTF::dataFile());
dataLogF("\n");
}
if (m_verbose)
dataLog(" tail vars: ", block->valuesAtTail, "\n");
}
void performForwardCFA()
......