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
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 139e7db..a0cb27a 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,142 @@
+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
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 24624f9..c37e9fa 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -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 */,
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
index 269499c..0176bcc0 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
@@ -35,7 +35,7 @@
 void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
 {
     if (!arrayModes) {
-        out.print("0:<empty>");
+        out.print("<empty>");
         return;
     }
     
@@ -44,34 +44,33 @@
         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)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp b/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
index 6d21f5b..f3014fb 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
@@ -1,5 +1,5 @@
 /*
- * 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 @@
 
 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
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
index 0150113..cfebd47 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
@@ -74,6 +74,11 @@
     }
 }
 
+void CodeOrigin::dumpInContext(PrintStream& out, DumpContext*) const
+{
+    dump(out);
+}
+
 JSFunction* InlineCallFrame::calleeForCallFrame(ExecState* exec) const
 {
     if (!isClosureCall())
@@ -103,11 +108,11 @@
     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 @@
     out.print(">");
 }
 
+void InlineCallFrame::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
 } // namespace JSC
 
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h
index 199351c..e46cc7e 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.h
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h
@@ -88,6 +88,7 @@
     Vector<CodeOrigin> inlineStack() const;
     
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
 };
 
 struct InlineCallFrame {
@@ -113,6 +114,7 @@
     
     void dumpBriefFunctionInformation(PrintStream&) const;
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
 
     MAKE_PRINT_METHOD(InlineCallFrame, dumpBriefFunctionInformation, briefFunctionInformation);
 };
diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h
index c209db2..a73cf58 100644
--- a/Source/JavaScriptCore/bytecode/Operands.h
+++ b/Source/JavaScriptCore/bytecode/Operands.h
@@ -1,5 +1,5 @@
 /*
- * 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 {
     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 @@
         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
diff --git a/Source/JavaScriptCore/bytecode/OperandsInlines.h b/Source/JavaScriptCore/bytecode/OperandsInlines.h
new file mode 100644
index 0000000..160763b
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/OperandsInlines.h
@@ -0,0 +1,53 @@
+/*
+ * 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
+
diff --git a/Source/JavaScriptCore/bytecode/StructureSet.h b/Source/JavaScriptCore/bytecode/StructureSet.h
index 35f87bd..be182fb 100644
--- a/Source/JavaScriptCore/bytecode/StructureSet.h
+++ b/Source/JavaScriptCore/bytecode/StructureSet.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 @@
         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;
     
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
index fdc088b..cd60a0f 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
@@ -252,11 +252,20 @@
 
 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(")");
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index fd0ec9e..b09423e 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -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 @@
     }
     
     bool isClear() const { return m_type == SpecNone; }
+    bool operator!() const { return isClear(); }
     
     void makeTop()
     {
@@ -251,6 +253,7 @@
     
     void checkConsistency() const;
     
+    void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
     
     // A great way to think about the difference between m_currentKnownStructure and
diff --git a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
index 175af17..d149fc6 100644
--- a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
@@ -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 @@
         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 @@
         }
         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()
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.cpp b/Source/JavaScriptCore/dfg/DFGCommon.cpp
index 811a43c..adb08b5 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCommon.cpp
@@ -30,15 +30,6 @@
 
 #include "DFGNode.h"
 
-namespace JSC { namespace DFG {
-
-void NodePointerTraits::dump(Node* value, PrintStream& out)
-{
-    out.print(value);
-}
-
-} } // namespace JSC::DFG
-
 namespace WTF {
 
 using namespace JSC::DFG;
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index dd20ed8..68199a8 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -78,7 +78,7 @@
 
 struct NodePointerTraits {
     static Node* defaultValue() { return 0; }
-    static void dump(Node* value, PrintStream& out);
+    static bool isEmptyForDump(Node* value) { return !value; }
 };
 
 // Use RefChildren if the child ref counts haven't already been adjusted using
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
index 0157800..53e86c7 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
@@ -102,7 +102,7 @@
             continue;
         dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNode);
         append(result, out, previousOrigin);
-        m_graph.dumpBlockHeader(out, prefix, block, Graph::DumpLivePhisOnly);
+        m_graph.dumpBlockHeader(out, prefix, block, Graph::DumpLivePhisOnly, &m_dumpContext);
         append(result, out, previousOrigin);
         Node* lastNodeForDisassembly = block->at(0);
         for (size_t i = 0; i < block->size(); ++i) {
@@ -125,11 +125,11 @@
             dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeForDisassembly);
             append(result, out, previousOrigin);
             previousOrigin = block->at(i)->codeOrigin;
-            if (m_graph.dumpCodeOrigin(out, prefix, lastNode, block->at(i))) {
+            if (m_graph.dumpCodeOrigin(out, prefix, lastNode, block->at(i), &m_dumpContext)) {
                 append(result, out, previousOrigin);
                 previousOrigin = block->at(i)->codeOrigin;
             }
-            m_graph.dump(out, prefix, block->at(i));
+            m_graph.dump(out, prefix, block->at(i), &m_dumpContext);
             lastNode = block->at(i);
             lastNodeForDisassembly = block->at(i);
         }
@@ -140,6 +140,8 @@
     append(result, out, previousOrigin);
     dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, 0);
     append(result, out, previousOrigin);
+    m_dumpContext.dump(out, prefix);
+    append(result, out, previousOrigin);
     
     return result;
 }
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.h b/Source/JavaScriptCore/dfg/DFGDisassembler.h
index c0cf130..0be1645 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.h
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.h
@@ -31,6 +31,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGCommon.h"
+#include "DumpContext.h"
 #include "LinkBuffer.h"
 #include "MacroAssembler.h"
 #include <wtf/HashMap.h>
@@ -88,6 +89,7 @@
     void dumpDisassembly(PrintStream&, const char* prefix, LinkBuffer&, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, Node* context);
     
     Graph& m_graph;
+    DumpContext m_dumpContext;
     MacroAssembler::Label m_startOfCode;
     Vector<MacroAssembler::Label> m_labelForBlockIndex;
     HashMap<Node*, MacroAssembler::Label> m_labelForNode;
diff --git a/Source/JavaScriptCore/dfg/DFGFlushFormat.h b/Source/JavaScriptCore/dfg/DFGFlushFormat.h
index 25a8748..7c75406 100644
--- a/Source/JavaScriptCore/dfg/DFGFlushFormat.h
+++ b/Source/JavaScriptCore/dfg/DFGFlushFormat.h
@@ -32,6 +32,7 @@
 
 #include "DFGNodeFlags.h"
 #include "DFGUseKind.h"
+#include "DumpContext.h"
 #include <wtf/PrintStream.h>
 
 namespace JSC { namespace DFG {
@@ -88,6 +89,11 @@
 
 void printInternal(PrintStream&, JSC::DFG::FlushFormat);
 
+inline JSC::DFG::FlushFormat inContext(JSC::DFG::FlushFormat format, JSC::DumpContext*)
+{
+    return format;
+}
+
 } // namespace WTF
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGFlushLivenessAnalysisPhase.cpp b/Source/JavaScriptCore/dfg/DFGFlushLivenessAnalysisPhase.cpp
index c9bc6d3..6b9161f 100644
--- a/Source/JavaScriptCore/dfg/DFGFlushLivenessAnalysisPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFlushLivenessAnalysisPhase.cpp
@@ -32,6 +32,7 @@
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
 #include "DFGPhase.h"
+#include "OperandsInlines.h"
 #include "Operations.h"
 
 namespace JSC { namespace DFG {
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 5fee787..937249e 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -31,6 +31,7 @@
 #include "DFGClobberSet.h"
 #include "DFGVariableAccessDataDump.h"
 #include "FunctionExecutableDump.h"
+#include "OperandsInlines.h"
 #include "Operations.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/ListDump.h>
@@ -77,7 +78,7 @@
         out.print(" ");
 }
 
-bool Graph::dumpCodeOrigin(PrintStream& out, const char* prefix, Node* previousNode, Node* currentNode)
+bool Graph::dumpCodeOrigin(PrintStream& out, const char* prefix, Node* previousNode, Node* currentNode, DumpContext* context)
 {
     if (!previousNode)
         return false;
@@ -102,7 +103,7 @@
     for (unsigned i = previousInlineStack.size(); i-- > indexOfDivergence;) {
         out.print(prefix);
         printWhiteSpace(out, i * 2);
-        out.print("<-- ", *previousInlineStack[i].inlineCallFrame, "\n");
+        out.print("<-- ", inContext(*previousInlineStack[i].inlineCallFrame, context), "\n");
         hasPrinted = true;
     }
     
@@ -110,7 +111,7 @@
     for (unsigned i = indexOfDivergence; i < currentInlineStack.size(); ++i) {
         out.print(prefix);
         printWhiteSpace(out, i * 2);
-        out.print("--> ", *currentInlineStack[i].inlineCallFrame, "\n");
+        out.print("--> ", inContext(*currentInlineStack[i].inlineCallFrame, context), "\n");
         hasPrinted = true;
     }
     
@@ -127,7 +128,7 @@
     printWhiteSpace(out, amountOfNodeWhiteSpace(node));
 }
 
-void Graph::dump(PrintStream& out, const char* prefix, Node* node)
+void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext* context)
 {
     NodeType op = node->op();
 
@@ -190,11 +191,11 @@
     if (node->hasIdentifier())
         out.print(comma, "id", node->identifierNumber(), "{", identifiers()[node->identifierNumber()], "}");
     if (node->hasStructureSet())
-        out.print(comma, node->structureSet());
+        out.print(comma, inContext(node->structureSet(), context));
     if (node->hasStructure())
-        out.print(comma, *node->structure());
+        out.print(comma, inContext(*node->structure(), context));
     if (node->hasStructureTransitionData())
-        out.print(comma, *node->structureTransitionData().previousStructure, " -> ", *node->structureTransitionData().newStructure);
+        out.print(comma, inContext(*node->structureTransitionData().previousStructure, context), " -> ", inContext(*node->structureTransitionData().newStructure, context));
     if (node->hasFunction()) {
         out.print(comma, "function(", RawPointer(node->function()), ", ");
         if (node->function()->inherits(&JSFunction::s_info)) {
@@ -240,7 +241,7 @@
         out.print(node->startConstant(), ":[");
         CommaPrinter anotherComma;
         for (unsigned i = 0; i < node->numConstants(); ++i)
-            out.print(anotherComma, m_codeBlock->constantBuffer(node->startConstant())[i]);
+            out.print(anotherComma, inContext(m_codeBlock->constantBuffer(node->startConstant())[i], context));
         out.print("]");
     }
     if (node->hasIndexingType())
@@ -252,10 +253,10 @@
     if (op == JSConstant) {
         out.print(comma, "$", node->constantNumber());
         JSValue value = valueOfJSConstant(node);
-        out.print(" = ", value);
+        out.print(" = ", inContext(value, context));
     }
     if (op == WeakJSConstant)
-        out.print(comma, RawPointer(node->weakConstant()), " (structure: ", *node->weakConstant()->structure(), ")");
+        out.print(comma, RawPointer(node->weakConstant()), " (", inContext(*node->weakConstant()->structure(), context), ")");
     if (node->isBranch() || node->isJump())
         out.print(comma, "T:", *node->takenBlock());
     if (node->isBranch())
@@ -264,7 +265,7 @@
         SwitchData* data = node->switchData();
         out.print(comma, data->kind);
         for (unsigned i = 0; i < data->cases.size(); ++i)
-            out.print(comma, data->cases[i].value, ":", *data->cases[i].target);
+            out.print(comma, inContext(data->cases[i].value, context), ":", *data->cases[i].target);
         out.print(comma, "default:", *data->fallThrough);
     }
     ClobberSet reads;
@@ -288,9 +289,9 @@
     out.print("\n");
 }
 
-void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode)
+void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode, DumpContext* context)
 {
-    out.print(prefix, "Block ", *block, " (", block->at(0)->codeOrigin, "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
+    out.print(prefix, "Block ", *block, " (", inContext(block->at(0)->codeOrigin, context), "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
     out.print(prefix, "  Predecessors:");
     for (size_t i = 0; i < block->predecessors.size(); ++i)
         out.print(" ", *block->predecessors[i]);
@@ -353,36 +354,33 @@
     }
 }
 
-void Graph::dump(PrintStream& out)
+void Graph::dump(PrintStream& out, DumpContext* context)
 {
+    DumpContext myContext;
+    if (!context)
+        context = &myContext;
+    
+    dataLog("\n");
     dataLog("DFG for ", CodeBlockWithJITType(m_codeBlock, JITCode::DFGJIT), ":\n");
     dataLog("  Fixpoint state: ", m_fixpointState, "; Form: ", m_form, "; Unification state: ", m_unificationState, "; Ref count state: ", m_refCountState, "\n");
-
-    out.print("  ArgumentPosition size: ", m_argumentPositions.size(), "\n");
-    for (size_t i = 0; i < m_argumentPositions.size(); ++i) {
-        out.print("    #", i, ": ");
-        ArgumentPosition& arguments = m_argumentPositions[i];
-        arguments.dump(out, this);
-    }
-
+    dataLog("\n");
+    
     Node* lastNode = 0;
     for (size_t b = 0; b < m_blocks.size(); ++b) {
         BasicBlock* block = m_blocks[b].get();
         if (!block)
             continue;
-        dumpBlockHeader(out, "", block, DumpAllPhis);
+        dumpBlockHeader(out, "", block, DumpAllPhis, context);
         switch (m_form) {
         case LoadStore:
         case ThreadedCPS: {
             out.print("  vars before: ");
             if (block->cfaHasVisited)
-                out.print(block->valuesAtHead);
+                out.print(inContext(block->valuesAtHead, context));
             else
                 out.print("<empty>");
             out.print("\n");
-            out.print("  var links: ");
-            dumpOperands(block->variablesAtHead, out);
-            out.print("\n");
+            out.print("  var links: ", block->variablesAtHead, "\n");
             break;
         }
             
@@ -391,12 +389,12 @@
             out.print("  Flush format: ", block->ssa->flushFormatAtHead, "\n");
             out.print("  Availability: ", block->ssa->availabilityAtHead, "\n");
             out.print("  Live: ", nodeListDump(block->ssa->liveAtHead), "\n");
-            out.print("  Values: ", nodeMapDump(block->ssa->valuesAtHead), "\n");
+            out.print("  Values: ", nodeMapDump(block->ssa->valuesAtHead, context), "\n");
             break;
         } }
         for (size_t i = 0; i < block->size(); ++i) {
-            dumpCodeOrigin(out, "", lastNode, block->at(i));
-            dump(out, "", block->at(i));
+            dumpCodeOrigin(out, "", lastNode, block->at(i), context);
+            dump(out, "", block->at(i), context);
             lastNode = block->at(i);
         }
         switch (m_form) {
@@ -404,13 +402,11 @@
         case ThreadedCPS: {
             out.print("  vars after: ");
             if (block->cfaHasVisited)
-                out.print(block->valuesAtTail);
+                out.print(inContext(block->valuesAtTail, context));
             else
                 out.print("<empty>");
             out.print("\n");
-            out.print("  var links: ");
-            dumpOperands(block->variablesAtTail, out);
-            out.print("\n");
+            out.print("  var links: ", block->variablesAtTail, "\n");
             break;
         }
             
@@ -419,9 +415,15 @@
             out.print("  Flush format: ", block->ssa->flushFormatAtTail, "\n");
             out.print("  Availability: ", block->ssa->availabilityAtTail, "\n");
             out.print("  Live: ", nodeListDump(block->ssa->liveAtTail), "\n");
-            out.print("  Values: ", nodeMapDump(block->ssa->valuesAtTail), "\n");
+            out.print("  Values: ", nodeMapDump(block->ssa->valuesAtTail, context), "\n");
             break;
         } }
+        dataLog("\n");
+    }
+    
+    if (!myContext.isEmpty()) {
+        myContext.dump(WTF::dataFile());
+        dataLog("\n");
     }
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index a9bbf5b..9eac443 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -157,17 +157,17 @@
     }
 
     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
-    void dump(PrintStream& = WTF::dataFile());
+    void dump(PrintStream& = WTF::dataFile(), DumpContext* = 0);
     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
-    void dumpBlockHeader(PrintStream&, const char* prefix, BasicBlock*, PhiNodeDumpMode);
+    void dumpBlockHeader(PrintStream&, const char* prefix, BasicBlock*, PhiNodeDumpMode, DumpContext* context);
     void dump(PrintStream&, Edge);
-    void dump(PrintStream&, const char* prefix, Node*);
+    void dump(PrintStream&, const char* prefix, Node*, DumpContext* = 0);
     static int amountOfNodeWhiteSpace(Node*);
     static void printNodeWhiteSpace(PrintStream&, Node*);
 
     // Dump the code origin of the given node as a diff from the code origin of the
     // preceding node. Returns true if anything was printed.
-    bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode);
+    bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode, DumpContext* context);
 
     SpeculatedType getJSConstantSpeculation(Node* node)
     {
diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
index c7b05ed..befcfbe 100644
--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
@@ -111,11 +111,11 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-void LazyJSValue::dump(PrintStream& out) const
+void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     switch (m_kind) {
     case KnownValue:
-        value().dump(out);
+        value().dumpInContext(out, context);
         return;
     case SingleCharacterString:
         out.print("Lazy:SingleCharacterString(");
@@ -129,6 +129,11 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void LazyJSValue::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
index 9d6d031..37a0726 100644
--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
@@ -114,6 +114,7 @@
     }
     
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
     
 private:
     union {
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index ba402a7..3195d26 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -1435,9 +1435,19 @@
 }
 
 template<typename T>
-CString nodeMapDump(const T& nodeMap)
+CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
 {
-    return sortedMapDump(nodeMap, nodeComparator);
+    Vector<typename T::KeyType> keys;
+    for (
+        typename T::const_iterator iter = nodeMap.begin();
+        iter != nodeMap.end(); ++iter)
+        keys.append(iter->key);
+    std::sort(keys.begin(), keys.end(), nodeComparator);
+    StringPrintStream out;
+    CommaPrinter comma;
+    for(unsigned i = 0; i < keys.size(); ++i)
+        out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
+    return out.toCString();
 }
 
 } } // namespace JSC::DFG
@@ -1447,7 +1457,11 @@
 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
 void printInternal(PrintStream&, JSC::DFG::Node*);
 
+inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
+
 } // namespace WTF
 
+using WTF::inContext;
+
 #endif
 #endif
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
index 4202da0..79c4e04 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
@@ -47,7 +47,7 @@
         dataLogF(" -> %p ", codeOrigin.inlineCallFrame->executable.get());
     }
     dataLogF(") at JIT offset 0x%x  ", m_jit.debugOffset());
-    dumpOperands(operands, WTF::dataFile());
+    dataLog(operands);
 #endif
     
     if (Options::printEachOSRExit()) {
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
index 064a0be..15604a5 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
@@ -47,7 +47,7 @@
         dataLogF(" -> %p ", codeOrigin.inlineCallFrame->executable.get());
     }
     dataLogF(")  ");
-    dumpOperands(operands, WTF::dataFile());
+    dataLog(operands);
 #endif
 
     if (Options::printEachOSRExit()) {
diff --git a/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h b/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
index 29f7bee..54d3bd2 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
@@ -32,6 +32,7 @@
 
 #include "JSCell.h"
 #include "SpeculatedType.h"
+#include "DumpContext.h"
 #include "StructureSet.h"
 
 namespace JSC { namespace DFG {
@@ -307,7 +308,7 @@
         return m_structure == other.m_structure;
     }
     
-    void dump(PrintStream& out) const
+    void dumpInContext(PrintStream& out, DumpContext* context) const
     {
         if (isTop()) {
             out.print("TOP");
@@ -316,10 +317,15 @@
         
         out.print("[");
         if (m_structure)
-            out.print(*m_structure);
+            out.print(inContext(*m_structure, context));
         out.print("]");
     }
 
+    void dump(PrintStream& out) const
+    {
+        dumpInContext(out, 0);
+    }
+
 private:
     static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
     
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.cpp b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
index 54815cd..b90c5cf 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
@@ -32,7 +32,7 @@
 
 namespace JSC { namespace FTL {
 
-void ExitValue::dump(PrintStream& out) const
+void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     switch (kind()) {
     case InvalidExitValue:
@@ -45,7 +45,7 @@
         out.print("Argument(", exitArgument(), ")");
         return;
     case ExitValueConstant:
-        out.print("Constant(", constant(), ")");
+        out.print("Constant(", inContext(constant(), context), ")");
         return;
     case ExitValueInJSStack:
         out.print("InJSStack");
@@ -61,6 +61,11 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void ExitValue::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.h b/Source/JavaScriptCore/ftl/FTLExitValue.h
index ce888a1..5814fc9 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.h
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.h
@@ -135,6 +135,7 @@
     }
     
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
     
 private:
     ExitValueKind m_kind;
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index f1a4646..e377059 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -39,6 +39,7 @@
 #include "FTLThunks.h"
 #include "FTLValueSource.h"
 #include "LinkBuffer.h"
+#include "OperandsInlines.h"
 #include "Operations.h"
 #include <wtf/ProcessID.h>
 
diff --git a/Source/JavaScriptCore/ftl/FTLValueSource.cpp b/Source/JavaScriptCore/ftl/FTLValueSource.cpp
index cad0261..a559521 100644
--- a/Source/JavaScriptCore/ftl/FTLValueSource.cpp
+++ b/Source/JavaScriptCore/ftl/FTLValueSource.cpp
@@ -56,6 +56,11 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void ValueSource::dumpInContext(PrintStream& out, DumpContext*) const
+{
+    dump(out);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
diff --git a/Source/JavaScriptCore/ftl/FTLValueSource.h b/Source/JavaScriptCore/ftl/FTLValueSource.h
index a0bd705..16719ff 100644
--- a/Source/JavaScriptCore/ftl/FTLValueSource.h
+++ b/Source/JavaScriptCore/ftl/FTLValueSource.h
@@ -78,6 +78,7 @@
     }
     
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
 
 private:
     uintptr_t m_value;
diff --git a/Source/JavaScriptCore/runtime/DumpContext.cpp b/Source/JavaScriptCore/runtime/DumpContext.cpp
new file mode 100644
index 0000000..84c80bb
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/DumpContext.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 COMPUTER, 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 COMPUTER, 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. 
+ */
+
+#include "config.h"
+#include "DumpContext.h"
+
+namespace JSC {
+
+DumpContext::DumpContext() { }
+DumpContext::~DumpContext() { }
+
+bool DumpContext::isEmpty() const
+{
+    return structures.isEmpty();
+}
+
+void DumpContext::dump(PrintStream& out, const char* prefix) const
+{
+    structures.dump(out, prefix);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/DumpContext.h b/Source/JavaScriptCore/runtime/DumpContext.h
new file mode 100644
index 0000000..e24ced0
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/DumpContext.h
@@ -0,0 +1,48 @@
+/*
+ * 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 COMPUTER, 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 COMPUTER, 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 DumpContext_h
+#define DumpContext_h
+
+#include "Structure.h"
+#include <wtf/PrintStream.h>
+#include <wtf/StringHashDumpContext.h>
+
+namespace JSC {
+
+struct DumpContext {
+    DumpContext();
+    ~DumpContext();
+    
+    bool isEmpty() const;
+    
+    void dump(PrintStream&, const char* prefix = "") const;
+    
+    StringHashDumpContext<Structure> structures;
+};
+
+} // namespace JSC
+
+#endif // DumpContext_h
diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.cpp b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
index 644a4f1..6e266c4 100644
--- a/Source/JavaScriptCore/runtime/JSCJSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
@@ -186,6 +186,11 @@
 
 void JSValue::dump(PrintStream& out) const
 {
+    dumpInContext(out, 0);
+}
+
+void JSValue::dumpInContext(PrintStream& out, DumpContext* context) const
+{
     if (!*this)
         out.print("<JSValue()>");
     else if (isInt32())
@@ -217,12 +222,10 @@
                 out.print(" (unresolved)");
             out.print(": ", impl);
         } else if (asCell()->inherits(&Structure::s_info))
-            out.print("Structure: ", *jsCast<Structure*>(asCell()));
+            out.print("Structure: ", inContext(*jsCast<Structure*>(asCell()), context));
         else {
             out.print("Cell: ", RawPointer(asCell()));
-            if (isObject() && asObject(*this)->butterfly())
-                out.print("->", RawPointer(asObject(*this)->butterfly()));
-            out.print(" (", *asCell()->structure(), ")");
+            out.print(" (", inContext(*asCell()->structure(), context), ")");
         }
     } else if (isTrue())
         out.print("True");
diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.h b/Source/JavaScriptCore/runtime/JSCJSValue.h
index 4196347..e46e8b4 100644
--- a/Source/JavaScriptCore/runtime/JSCJSValue.h
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.h
@@ -66,6 +66,7 @@
 #endif
 
 struct ClassInfo;
+struct DumpContext;
 struct Instruction;
 struct MethodTable;
 
@@ -263,6 +264,7 @@
     JSValue structureOrUndefined() const;
 
     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
 
     JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
 
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 5320acf..339384e 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -1034,6 +1034,24 @@
     out.print("]");
 }
 
+void Structure::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    if (context)
+        context->structures.dumpBrief(this, out);
+    else
+        dump(out);
+}
+
+void Structure::dumpBrief(PrintStream& out, const CString& string) const
+{
+    out.print("%", string, ":", classInfo()->className);
+}
+
+void Structure::dumpContextHeader(PrintStream& out)
+{
+    out.print("Structures:");
+}
+
 #if DO_PROPERTYMAP_CONSTENCY_CHECK
 
 void PropertyTable::checkConsistency()
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 165ca27..d802382 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -57,6 +57,7 @@
 class StructureChain;
 class SlotVisitor;
 class JSString;
+struct DumpContext;
 
 // The out-of-line property storage capacity to use when first allocating out-of-line
 // storage. Note that all objects start out without having any out-of-line storage;
@@ -349,6 +350,10 @@
     }
     
     void dump(PrintStream&) const;
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dumpBrief(PrintStream&, const CString&) const;
+    
+    static void dumpContextHeader(PrintStream&);
     
     static JS_EXPORTDATA const ClassInfo s_info;