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