Commit 0bfcc38a authored by fpizlo@apple.com's avatar fpizlo@apple.com

It should be easy to find code blocks in debug dumps

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

Source/JavaScriptCore: 

Reviewed by Goeffrey Garen.

This gives CodeBlock a relatively strong, but also relatively compact, hash. We compute
it lazily so that it only impacts run-time when debug support is enabled. We stringify
it smartly so that it's short and easy to type. We base it on the source code so that
the optimization level is irrelevant. And, we use SHA1 since it's already in our code
base. Now, when a piece of code wants to print some debugging to say that it's operating
on some code block, it can use this CodeBlockHash instead of memory addresses.

This also takes CodeBlock debugging into the new world of print() and dataLog(). In
particular, CodeBlock::dump() corresponds to the thing you want printed if you do:

dataLog("I heart ", *myCodeBlock);

Probably, you want to just print some identifying information at this point rather than
the full bytecode dump. So, the existing CodeBlock::dump() has been renamed to
CodeBlock::dumpBytecode(), and CodeBlock::dump() now prints the CodeBlockHash plus just
a few little tidbits.
        
Here's an example of CodeBlock::dump() output:
        
EkILzr:[0x103883a00, BaselineFunctionCall]
        
EkILzr is the CodeBlockHash. 0x103883a00 is the CodeBlock's address in memory. The other
part is self-explanatory.

Finally, this new notion of CodeBlockHash is available for other purposes like bisecting
breakage. As such CodeBlockHash has all of the comparison operator overloads. When
bisecting in DFGDriver.cpp, you can now say things like:
        
if (codeBlock->hash() < CodeBlockHash("CAAAAA"))
    return false;
        
And yes, CAAAAA is near the median hash, and the largest one is smaller than E99999. Such
is life when you use base 62 to encode a 32-bit number.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CallLinkInfo.h:
(CallLinkInfo):
(JSC::CallLinkInfo::specializationKind):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::hash):
(JSC):
(JSC::CodeBlock::dumpAssumingJITType):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::resetStubInternal):
(JSC::CodeBlock::reoptimize):
(JSC::ProgramCodeBlock::jettison):
(JSC::EvalCodeBlock::jettison):
(JSC::FunctionCodeBlock::jettison):
(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::tallyFrequentExitSites):
(JSC::CodeBlock::dumpValueProfiles):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::specializationKind):
(CodeBlock):
(JSC::CodeBlock::getJITType):
* bytecode/CodeBlockHash.cpp: Added.
(JSC):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::dump):
* bytecode/CodeBlockHash.h: Added.
(JSC):
(CodeBlockHash):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::hash):
(JSC::CodeBlockHash::operator==):
(JSC::CodeBlockHash::operator!=):
(JSC::CodeBlockHash::operator<):
(JSC::CodeBlockHash::operator>):
(JSC::CodeBlockHash::operator<=):
(JSC::CodeBlockHash::operator>=):
* bytecode/CodeBlockWithJITType.h: Added.
(JSC):
(CodeBlockWithJITType):
(JSC::CodeBlockWithJITType::CodeBlockWithJITType):
(JSC::CodeBlockWithJITType::dump):
* bytecode/CodeOrigin.cpp: Added.
(JSC):
(JSC::CodeOrigin::inlineDepthForCallFrame):
(JSC::CodeOrigin::inlineDepth):
(JSC::CodeOrigin::inlineStack):
(JSC::InlineCallFrame::hash):
* bytecode/CodeOrigin.h:
(InlineCallFrame):
(JSC::InlineCallFrame::specializationKind):
(JSC):
* bytecode/CodeType.cpp: Added.
(WTF):
(WTF::printInternal):
* bytecode/CodeType.h:
(WTF):
* bytecode/ExecutionCounter.cpp:
(JSC::ExecutionCounter::dump):
* bytecode/ExecutionCounter.h:
(ExecutionCounter):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::dump):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dumpCodeOrigin):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOperations.cpp:
* dfg/DFGRepatch.cpp:
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::emitPutReplaceStub):
(JSC::DFG::emitPutTransitionStub):
(JSC::DFG::dfgLinkClosureCall):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::dumpCallFrame):
* jit/JITCode.cpp: Added.
(WTF):
(WTF::printInternal):
* jit/JITCode.h:
(JSC::JITCode::jitType):
(WTF):
* jit/JITDisassembler.cpp:
(JSC::JITDisassembler::dump):
(JSC::JITDisassembler::dumpForInstructions):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
(JSC::JIT::privateCompileGetByVal):
(JSC::JIT::privateCompilePutByVal):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/CodeSpecializationKind.cpp: Added.
(WTF):
(WTF::printInternal):
* runtime/CodeSpecializationKind.h:
(JSC::specializationFromIsCall):
(JSC):
(JSC::specializationFromIsConstruct):
(WTF):
* runtime/Executable.cpp:
(JSC::ExecutableBase::hashFor):
(JSC):
(JSC::NativeExecutable::hashFor):
(JSC::ScriptExecutable::hashFor):
* runtime/Executable.h:
(ExecutableBase):
(NativeExecutable):
(ScriptExecutable):
(JSC::ScriptExecutable::source):

Source/WTF: 

Reviewed by Geoffrey Garen.

Changed RawPointer to accept both const void* and void*, and use the former internally.
        
Cleaned up SHA1 so that the functionality already used internally for self-testing is
available via the API. This includes addBytes(CString) and computing hex digests.

* wtf/RawPointer.h:
(WTF::RawPointer::RawPointer):
(RawPointer):
(WTF::RawPointer::value):
* wtf/SHA1.cpp:
(WTF::expectSHA1):
(WTF::SHA1::hexDigest):
(WTF::SHA1::computeHexDigest):
* wtf/SHA1.h:
(WTF::SHA1::addBytes):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@136199 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent ce1a6e23
......@@ -45,6 +45,9 @@ SET(JavaScriptCore_SOURCES
bytecode/CallLinkInfo.cpp
bytecode/CallLinkStatus.cpp
bytecode/CodeBlock.cpp
bytecode/CodeBlockHash.cpp
bytecode/CodeOrigin.cpp
bytecode/CodeType.cpp
bytecode/DFGExitProfile.cpp
bytecode/ExecutionCounter.cpp
bytecode/GetByIdStatus.cpp
......@@ -150,6 +153,7 @@ SET(JavaScriptCore_SOURCES
jit/JITArithmetic.cpp
jit/JITCall32_64.cpp
jit/JITCall.cpp
jit/JITCode.cpp
jit/JIT.cpp
jit/JITDisassembler.cpp
jit/JITExceptions.cpp
......@@ -182,6 +186,7 @@ SET(JavaScriptCore_SOURCES
runtime/BooleanPrototype.cpp
runtime/CallData.cpp
runtime/CodeCache.cpp
runtime/CodeSpecializationKind.cpp
runtime/CommonIdentifiers.cpp
runtime/Completion.cpp
runtime/ConstructData.cpp
......
2012-11-29 Filip Pizlo <fpizlo@apple.com>
It should be easy to find code blocks in debug dumps
https://bugs.webkit.org/show_bug.cgi?id=103623
Reviewed by Goeffrey Garen.
This gives CodeBlock a relatively strong, but also relatively compact, hash. We compute
it lazily so that it only impacts run-time when debug support is enabled. We stringify
it smartly so that it's short and easy to type. We base it on the source code so that
the optimization level is irrelevant. And, we use SHA1 since it's already in our code
base. Now, when a piece of code wants to print some debugging to say that it's operating
on some code block, it can use this CodeBlockHash instead of memory addresses.
This also takes CodeBlock debugging into the new world of print() and dataLog(). In
particular, CodeBlock::dump() corresponds to the thing you want printed if you do:
dataLog("I heart ", *myCodeBlock);
Probably, you want to just print some identifying information at this point rather than
the full bytecode dump. So, the existing CodeBlock::dump() has been renamed to
CodeBlock::dumpBytecode(), and CodeBlock::dump() now prints the CodeBlockHash plus just
a few little tidbits.
Here's an example of CodeBlock::dump() output:
EkILzr:[0x103883a00, BaselineFunctionCall]
EkILzr is the CodeBlockHash. 0x103883a00 is the CodeBlock's address in memory. The other
part is self-explanatory.
Finally, this new notion of CodeBlockHash is available for other purposes like bisecting
breakage. As such CodeBlockHash has all of the comparison operator overloads. When
bisecting in DFGDriver.cpp, you can now say things like:
if (codeBlock->hash() < CodeBlockHash("CAAAAA"))
return false;
And yes, CAAAAA is near the median hash, and the largest one is smaller than E99999. Such
is life when you use base 62 to encode a 32-bit number.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CallLinkInfo.h:
(CallLinkInfo):
(JSC::CallLinkInfo::specializationKind):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::hash):
(JSC):
(JSC::CodeBlock::dumpAssumingJITType):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::resetStubInternal):
(JSC::CodeBlock::reoptimize):
(JSC::ProgramCodeBlock::jettison):
(JSC::EvalCodeBlock::jettison):
(JSC::FunctionCodeBlock::jettison):
(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::tallyFrequentExitSites):
(JSC::CodeBlock::dumpValueProfiles):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::specializationKind):
(CodeBlock):
(JSC::CodeBlock::getJITType):
* bytecode/CodeBlockHash.cpp: Added.
(JSC):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::dump):
* bytecode/CodeBlockHash.h: Added.
(JSC):
(CodeBlockHash):
(JSC::CodeBlockHash::CodeBlockHash):
(JSC::CodeBlockHash::hash):
(JSC::CodeBlockHash::operator==):
(JSC::CodeBlockHash::operator!=):
(JSC::CodeBlockHash::operator<):
(JSC::CodeBlockHash::operator>):
(JSC::CodeBlockHash::operator<=):
(JSC::CodeBlockHash::operator>=):
* bytecode/CodeBlockWithJITType.h: Added.
(JSC):
(CodeBlockWithJITType):
(JSC::CodeBlockWithJITType::CodeBlockWithJITType):
(JSC::CodeBlockWithJITType::dump):
* bytecode/CodeOrigin.cpp: Added.
(JSC):
(JSC::CodeOrigin::inlineDepthForCallFrame):
(JSC::CodeOrigin::inlineDepth):
(JSC::CodeOrigin::inlineStack):
(JSC::InlineCallFrame::hash):
* bytecode/CodeOrigin.h:
(InlineCallFrame):
(JSC::InlineCallFrame::specializationKind):
(JSC):
* bytecode/CodeType.cpp: Added.
(WTF):
(WTF::printInternal):
* bytecode/CodeType.h:
(WTF):
* bytecode/ExecutionCounter.cpp:
(JSC::ExecutionCounter::dump):
* bytecode/ExecutionCounter.h:
(ExecutionCounter):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::dump):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dumpCodeOrigin):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOperations.cpp:
* dfg/DFGRepatch.cpp:
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::emitPutReplaceStub):
(JSC::DFG::emitPutTransitionStub):
(JSC::DFG::dfgLinkClosureCall):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::dumpCallFrame):
* jit/JITCode.cpp: Added.
(WTF):
(WTF::printInternal):
* jit/JITCode.h:
(JSC::JITCode::jitType):
(WTF):
* jit/JITDisassembler.cpp:
(JSC::JITDisassembler::dump):
(JSC::JITDisassembler::dumpForInstructions):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
(JSC::JIT::privateCompileGetByVal):
(JSC::JIT::privateCompilePutByVal):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/CodeSpecializationKind.cpp: Added.
(WTF):
(WTF::printInternal):
* runtime/CodeSpecializationKind.h:
(JSC::specializationFromIsCall):
(JSC):
(JSC::specializationFromIsConstruct):
(WTF):
* runtime/Executable.cpp:
(JSC::ExecutableBase::hashFor):
(JSC):
(JSC::NativeExecutable::hashFor):
(JSC::ScriptExecutable::hashFor):
* runtime/Executable.h:
(ExecutableBase):
(NativeExecutable):
(ScriptExecutable):
(JSC::ScriptExecutable::source):
2012-11-29 Michael Saboff <msaboff@apple.com>
Speculative Windows build fix after r136086.
......
......@@ -94,9 +94,14 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/CallLinkStatus.cpp \
Source/JavaScriptCore/bytecode/CallLinkStatus.h \
Source/JavaScriptCore/bytecode/CallReturnOffsetToBytecodeOffset.h \
Source/JavaScriptCore/bytecode/CodeType.cpp \
Source/JavaScriptCore/bytecode/CodeType.h \
Source/JavaScriptCore/bytecode/CodeBlock.cpp \
Source/JavaScriptCore/bytecode/CodeBlock.h \
Source/JavaScriptCore/bytecode/CodeBlockHash.cpp \
Source/JavaScriptCore/bytecode/CodeBlockHash.h \
Source/JavaScriptCore/bytecode/CodeBlockWithJITType.h \
Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
Source/JavaScriptCore/bytecode/CodeOrigin.h \
Source/JavaScriptCore/bytecode/Comment.h \
Source/JavaScriptCore/bytecode/DataFormat.h \
......@@ -399,6 +404,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/jit/JITArithmetic.cpp \
Source/JavaScriptCore/jit/JITCall32_64.cpp \
Source/JavaScriptCore/jit/JITCall.cpp \
Source/JavaScriptCore/jit/JITCode.cpp \
Source/JavaScriptCore/jit/JITCode.h \
Source/JavaScriptCore/jit/JITCompilationEffort.h \
Source/JavaScriptCore/jit/JITDisassembler.cpp \
......@@ -499,6 +505,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/ClassInfo.h \
Source/JavaScriptCore/runtime/CodeCache.cpp \
Source/JavaScriptCore/runtime/CodeCache.h \
Source/JavaScriptCore/runtime/CodeSpecializationKind.cpp \
Source/JavaScriptCore/runtime/CodeSpecializationKind.h \
Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
Source/JavaScriptCore/runtime/CommonIdentifiers.h \
......
......@@ -645,6 +645,14 @@
RelativePath="..\..\runtime\CodeCache.h"
>
</File>
<File
RelativePath="..\..\runtime\CodeSpecializationKind.cpp"
>
</File>
<File
RelativePath="..\..\runtime\CodeSpecializationKind.h"
>
</File>
<File
RelativePath="..\..\runtime\CommonIdentifiers.cpp"
>
......@@ -1629,6 +1637,22 @@
RelativePath="..\..\bytecode\CodeBlock.h"
>
</File>
<File
RelativePath="..\..\bytecode\CodeBlockHash.cpp"
>
</File>
<File
RelativePath="..\..\bytecode\CodeBlockHash.h"
>
</File>
<File
RelativePath="..\..\bytecode\CodeBlockWithJITType.h"
>
</File>
<File
RelativePath="..\..\bytecode\CodeOrigin.cpp"
>
</File>
<File
RelativePath="..\..\bytecode\CodeOrigin.h"
>
......@@ -1637,6 +1661,10 @@
RelativePath="..\..\bytecode\CodeType.h"
>
</File>
<File
RelativePath="..\..\bytecode\CodeType.cpp"
>
</File>
<File
RelativePath="..\..\bytecode\Comment.h"
>
......@@ -1981,6 +2009,10 @@
RelativePath="..\..\jit\JITCall32_64.cpp"
>
</File>
<File
RelativePath="..\..\jit\JITCode.cpp"
>
</File>
<File
RelativePath="..\..\jit\JITCode.h"
>
......
......@@ -170,6 +170,12 @@
0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */; };
0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */; };
0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */; };
0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8F943E1667632D00D61971 /* CodeBlockHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8F94421667633500D61971 /* CodeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F943F1667632D00D61971 /* CodeType.cpp */; };
0F8F94441667635400D61971 /* JITCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F94431667635200D61971 /* JITCode.cpp */; };
0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F9445166764EE00D61971 /* CodeOrigin.cpp */; };
0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */; };
0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */; };
......@@ -185,6 +191,7 @@
0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D336E165DBB8D005AD387 /* Disassembler.cpp */; };
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -968,6 +975,12 @@
0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = "<group>"; };
0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; };
0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeSpecializationKind.cpp; sourceTree = "<group>"; };
0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlockHash.cpp; sourceTree = "<group>"; };
0F8F943E1667632D00D61971 /* CodeBlockHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockHash.h; sourceTree = "<group>"; };
0F8F943F1667632D00D61971 /* CodeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeType.cpp; sourceTree = "<group>"; };
0F8F94431667635200D61971 /* JITCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCode.cpp; sourceTree = "<group>"; };
0F8F9445166764EE00D61971 /* CodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeOrigin.cpp; sourceTree = "<group>"; };
0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSymbolTableObject.cpp; sourceTree = "<group>"; };
0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSymbolTableObject.h; sourceTree = "<group>"; };
0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObject.cpp; sourceTree = "<group>"; };
......@@ -983,6 +996,7 @@
0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutByIdStatus.h; sourceTree = "<group>"; };
0F93329B14CA7DC10085F3C6 /* StructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureSet.h; sourceTree = "<group>"; };
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
0F9D336E165DBB8D005AD387 /* Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Disassembler.cpp; path = disassembler/Disassembler.cpp; sourceTree = "<group>"; };
0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicPutByIdList.cpp; sourceTree = "<group>"; };
0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicPutByIdList.h; sourceTree = "<group>"; };
......@@ -1838,6 +1852,7 @@
A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */,
86CC85A20EE79B7400288682 /* JITCall.cpp */,
146FE51111A710430087AE66 /* JITCall32_64.cpp */,
0F8F94431667635200D61971 /* JITCode.cpp */,
86CCEFDD0F413F8900FD7F9E /* JITCode.h */,
0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
......@@ -2136,6 +2151,7 @@
BCA62DFE0E2826230004F30D /* CallData.cpp */,
145C507F0D9DF63B0088F6B9 /* CallData.h */,
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */,
0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */,
65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */,
......@@ -2560,9 +2576,14 @@
0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */,
0F8F943E1667632D00D61971 /* CodeBlockHash.h */,
0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */,
969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
0F8F9445166764EE00D61971 /* CodeOrigin.cpp */,
0FBD7E671447998F00481315 /* CodeOrigin.h */,
0F8F943F1667632D00D61971 /* CodeType.cpp */,
0F0B83A514BCF50400885B4F /* CodeType.h */,
FEB63AA2159B9DA3008932A6 /* Comment.h */,
0F426A4A1460CD6B00131F8F /* DataFormat.h */,
......@@ -3054,6 +3075,8 @@
0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -3637,6 +3660,11 @@
0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
0F8F94441667635400D61971 /* JITCode.cpp in Sources */,
0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -55,6 +55,9 @@ SOURCES += \
bytecode/CallLinkInfo.cpp \
bytecode/CallLinkStatus.cpp \
bytecode/CodeBlock.cpp \
bytecode/CodeBlockHash.cpp \
bytecode/CodeOrigin.cpp \
bytecode/CodeType.cpp \
bytecode/DFGExitProfile.cpp \
bytecode/ExecutionCounter.cpp \
bytecode/GetByIdStatus.cpp \
......@@ -155,6 +158,7 @@ SOURCES += \
jit/JITArithmetic32_64.cpp \
jit/JITCall.cpp \
jit/JITCall32_64.cpp \
jit/JITCode.cpp \
jit/JIT.cpp \
jit/JITDisassembler.cpp \
jit/JITExceptions.cpp \
......@@ -191,6 +195,7 @@ SOURCES += \
runtime/BooleanPrototype.cpp \
runtime/CallData.cpp \
runtime/CodeCache.cpp \
runtime/CodeSpecializationKind.cpp \
runtime/CommonIdentifiers.cpp \
runtime/Completion.cpp \
runtime/ConstructData.cpp \
......
......@@ -28,6 +28,7 @@
#include "ClosureCallStubRoutine.h"
#include "CodeLocation.h"
#include "CodeSpecializationKind.h"
#include "JITWriteBarrier.h"
#include "JSFunction.h"
#include "Opcode.h"
......@@ -65,6 +66,11 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
if (isOnList())
remove();
}
CodeSpecializationKind specializationKind() const
{
return specializationFromIsConstruct(callType == Construct);
}
CodeLocationNearCall callReturnLocation;
CodeLocationDataLabelPtr hotPathBegin;
......
......@@ -62,6 +62,24 @@ namespace JSC {
using namespace DFG;
#endif
CodeBlockHash CodeBlock::hash() const
{
return CodeBlockHash(ownerExecutable()->source(), specializationKind());
}
void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
{
out.print("#", hash(), ":[", RawPointer(this), ", ", jitType, codeType());
if (codeType() == FunctionCode)
out.print(specializationKind());
out.print("]");
}
void CodeBlock::dump(PrintStream& out) const
{
dumpAssumingJITType(out, getJITType());
}
static String escapeQuotes(const String& str)
{
String result = str;
......@@ -480,7 +498,7 @@ void CodeBlock::printStructures(const Instruction* vPC)
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
}
void CodeBlock::dump()
void CodeBlock::dumpBytecode()
{
// We only use the ExecState* for things that don't actually lead to JS execution,
// like converting a JSString to a String. Hence the globalExec is appropriate.
......@@ -491,12 +509,12 @@ void CodeBlock::dump()
for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
++instructionCount;
dataLog(*this);
dataLogF(
"%lu m_instructions; %lu bytes at %p (%s); %d parameter(s); %d callee register(s); %d variable(s)",
": %lu m_instructions; %lu bytes; %d parameter(s); %d callee register(s); %d variable(s)",
static_cast<unsigned long>(instructions().size()),
static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
this, codeTypeToString(codeType()), m_numParameters, m_numCalleeRegisters,
m_numVars);
m_numParameters, m_numCalleeRegisters, m_numVars);
if (symbolTable() && symbolTable()->captureCount())
dataLogF("; %d captured var(s)", symbolTable()->captureCount());
if (usesArguments()) {
......@@ -512,7 +530,7 @@ void CodeBlock::dump()
const Instruction* begin = instructions().begin();
const Instruction* end = instructions().end();
for (const Instruction* it = begin; it != end; ++it)
dump(exec, begin, it);
dumpBytecode(exec, begin, it);
if (!m_identifiers.isEmpty()) {
dataLogF("\nIdentifiers:\n");
......@@ -607,7 +625,7 @@ void CodeBlock::dump()
dataLogF("\n");
}
void CodeBlock::dump(ExecState* exec, const Instruction* begin, const Instruction*& it)
void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const Instruction*& it)
{
int location = it - begin;
switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
......@@ -1458,11 +1476,11 @@ void CodeBlock::dump(ExecState* exec, const Instruction* begin, const Instructio
}
}
void CodeBlock::dump(unsigned bytecodeOffset)
void CodeBlock::dumpBytecode(unsigned bytecodeOffset)
{
ExecState* exec = m_globalObject->globalExec();
const Instruction* it = instructions().begin() + bytecodeOffset;
dump(exec, instructions().begin(), it);
dumpBytecode(exec, instructions().begin(), it);
}
#if DUMP_CODE_BLOCK_STATISTICS
......@@ -1892,7 +1910,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
m_instructions = WTF::RefCountedArray<Instruction>(instructions);
if (Options::dumpGeneratedBytecodes())
dump();
dumpBytecode();
m_globalData->finishedCompiling(this);
}
......@@ -2186,7 +2204,7 @@ void CodeBlock::finalizeUnconditionally()
for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
if (verboseUnlinking)
dataLogF("Clearing LLInt call from %p.\n", this);
dataLog("Clearing LLInt call from ", *this, "\n");
m_llintCallLinkInfos[i].unlink();
}
if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
......@@ -2199,14 +2217,14 @@ void CodeBlock::finalizeUnconditionally()
// Check if we're not live. If we are, then jettison.
if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
if (verboseUnlinking)
dataLogF("Code block %p (executable %p) has dead weak references, jettisoning during GC.\n", this, ownerExecutable());
dataLog(*this, " has dead weak references, jettisoning during GC.\n");
// Make sure that the baseline JIT knows that it should re-warm-up before
// optimizing.
alternative()->optimizeAfterWarmUp();
if (DFG::shouldShowDisassembly()) {
dataLogF("DFG CodeBlock %p will be jettisoned because of the following dead references:\n", this);
dataLog(*this, "will be jettisoned because of the following dead references:\n");
for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
WeakReferenceTransition& transition = m_dfgData->transitions[i];
JSCell* origin = transition.m_codeOrigin.get();
......@@ -2234,7 +2252,7 @@ void CodeBlock::finalizeUnconditionally()
for (size_t size = m_putToBaseOperations.size(), i = 0; i < size; ++i) {
if (m_putToBaseOperations[i].m_structure && !Heap::isMarked(m_putToBaseOperations[i].m_structure.get())) {
if (verboseUnlinking)
dataLogF("Clearing putToBase info in %p.\n", this);
dataLog("Clearing putToBase info in ", *this, "\n");
m_putToBaseOperations[i].m_structure.clear();
}
}
......@@ -2248,7 +2266,7 @@ void CodeBlock::finalizeUnconditionally()
m_resolveOperations[i].last().m_structure.clear();
if (m_resolveOperations[i].last().m_structure && !Heap::isMarked(m_resolveOperations[i].last().m_structure.get())) {
if (verboseUnlinking)
dataLogF("Clearing resolve info in %p.\n", this);
dataLog("Clearing resolve info in ", *this, "\n");
m_resolveOperations[i].last().m_structure.clear();
}
}
......@@ -2262,13 +2280,23 @@ void CodeBlock::finalizeUnconditionally()
if (ClosureCallStubRoutine* stub = callLinkInfo(i).stub.get()) {
if (!Heap::isMarked(stub->structure())
|| !Heap::isMarked(stub->executable())) {
if (verboseUnlinking)
dataLogF("Clearing closure call from %p to %p, stub routine %p.\n", this, stub->executable(), stub);
if (verboseUnlinking) {
dataLog(
"Clearing closure call from ", *this, " to ",
stub->executable()->hashFor(callLinkInfo(i).specializationKind()),
", stub routine ", RawPointer(stub), ".\n");
}
callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
}
} else if (!Heap::isMarked(callLinkInfo(i).callee.get())) {
if (verboseUnlinking)
dataLogF("Clearing call from %p to %p.\n", this, callLinkInfo(i).callee.get());
if (verboseUnlinking) {
dataLog(
"Clearing call from ", *this, " to ",
RawPointer(callLinkInfo(i).callee.get()), " (",
callLinkInfo(i).callee.get()->executable()->hashFor(
callLinkInfo(i).specializationKind()),
").\n");
}
callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
}
}
......@@ -2303,7 +2331,7 @@ void CodeBlock::resetStubInternal(RepatchBuffer& repatchBuffer, StructureStubInf
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
if (verboseUnlinking)
dataLogF("Clearing structure cache (kind %d) in %p.\n", stubInfo.accessType, this);
dataLog("Clearing structure cache (kind ", static_cast<int>(stubInfo.accessType), ") in ", *this, ".\n");
if (isGetByIdAccess(accessType)) {
if (getJITCode().jitType() == JITCode::DFGJIT)
......@@ -2769,7 +2797,7 @@ void CodeBlock::reoptimize()
ASSERT(replacement()->alternative() == this);