Do bytecode validation as part of testing
https://bugs.webkit.org/show_bug.cgi?id=124913
Source/JavaScriptCore:
Reviewed by Oliver Hunt.
Also fix some small bugs in the bytecode liveness analysis that I found by doing
this validation thingy.
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::isValidRegisterForLiveness):
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::validate):
(JSC::CodeBlock::beginValidationDidFail):
(JSC::CodeBlock::endValidationDidFail):
* bytecode/CodeBlock.h:
* runtime/Executable.cpp:
(JSC::ScriptExecutable::prepareForExecutionImpl):
* runtime/Options.h:
Source/WTF:
Reviewed by Oliver Hunt.
* GNUmakefile.list.am:
* WTF.vcxproj/WTF.vcxproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/FastBitVector.cpp: Added.
(WTF::FastBitVector::dump):
* wtf/FastBitVector.h:
(WTF::FastBitVector::resize):
(WTF::FastBitVector::bitCount):
(WTF::FastBitVector::arrayLength):
Tools:
Reviewed by Oliver Hunt.
* Scripts/run-jsc-stress-tests:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159825 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index b6fd4d2..f91006f 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -3422,4 +3422,58 @@
return "";
}
+void CodeBlock::validate()
+{
+ BytecodeLivenessAnalysis liveness(this); // Compute directly from scratch so it doesn't effect CodeBlock footprint.
+
+ FastBitVector liveAtHead = liveness.getLivenessInfoAtBytecodeOffset(0);
+
+ if (liveAtHead.numBits() != static_cast<size_t>(m_numCalleeRegisters)) {
+ beginValidationDidFail();
+ dataLog(" Wrong number of bits in result!\n");
+ dataLog(" Result: ", liveAtHead, "\n");
+ dataLog(" Bit count: ", liveAtHead.numBits(), "\n");
+ endValidationDidFail();
+ }
+
+ for (unsigned i = m_numCalleeRegisters; i--;) {
+ bool isCaptured = false;
+ VirtualRegister reg = virtualRegisterForLocal(i);
+
+ if (captureCount())
+ isCaptured = reg.offset() <= captureStart() && reg.offset() > captureEnd();
+
+ if (isCaptured) {
+ if (!liveAtHead.get(i)) {
+ beginValidationDidFail();
+ dataLog(" Variable loc", i, " is expected to be live because it is captured, but it isn't live.\n");
+ dataLog(" Result: ", liveAtHead, "\n");
+ endValidationDidFail();
+ }
+ } else {
+ if (liveAtHead.get(i)) {
+ beginValidationDidFail();
+ dataLog(" Variable loc", i, " is expected to be dead.\n");
+ dataLog(" Result: ", liveAtHead, "\n");
+ endValidationDidFail();
+ }
+ }
+ }
+}
+
+void CodeBlock::beginValidationDidFail()
+{
+ dataLog("Validation failure in ", *this, ":\n");
+ dataLog("\n");
+}
+
+void CodeBlock::endValidationDidFail()
+{
+ dataLog("\n");
+ dumpBytecode();
+ dataLog("\n");
+ dataLog("Validation failure.\n");
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
} // namespace JSC