op_to_this shouldn't use value profiling
https://bugs.webkit.org/show_bug.cgi?id=121920

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Currently it's the only opcode that uses m_singletonValue, which is unnecessary. Our current plan is
to remove m_singletonValue so that GenGC can have a simpler story for handling CodeBlocks/FunctionExecutables
during nursery collections.

This patch adds an inline cache for the Structure of to_this so it no longer depends on the ValueProfile's
m_singletonValue. Since nobody uses m_singletonValue now, this patch also removes m_singletonValue from
ValueProfile.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
(JSC::CodeBlock::updateAllValueProfilePredictions):
(JSC::CodeBlock::updateAllPredictions):
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::updateAllValueProfilePredictions):
(JSC::CodeBlock::updateAllPredictions):
* bytecode/LazyOperandValueProfile.cpp:
(JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
* bytecode/LazyOperandValueProfile.h:
* bytecode/ValueProfile.h:
(JSC::ValueProfileBase::ValueProfileBase):
(JSC::ValueProfileBase::briefDescription):
(JSC::ValueProfileBase::dump):
(JSC::ValueProfileBase::computeUpdatedPrediction):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emitSlow_op_to_this):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emitSlow_op_to_this):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):

LayoutTests:

Updated a couple tests that waited for two DFG compiles, but with this patch we
don't do two compiles any more, so we don't want to wait forever.

* js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-other.js:
* js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-string.js:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156468 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h
index 046b29b..0db9166 100644
--- a/Source/JavaScriptCore/bytecode/ValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/ValueProfile.h
@@ -55,7 +55,6 @@
         : m_bytecodeOffset(-1)
         , m_prediction(SpecNone)
         , m_numberOfSamplesInPrediction(0)
-        , m_singletonValueIsTop(false)
     {
         for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
             m_buckets[i] = JSValue::encode(JSValue());
@@ -65,7 +64,6 @@
         : m_bytecodeOffset(bytecodeOffset)
         , m_prediction(SpecNone)
         , m_numberOfSamplesInPrediction(0)
-        , m_singletonValueIsTop(false)
     {
         for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
             m_buckets[i] = JSValue::encode(JSValue());
@@ -117,23 +115,13 @@
         computeUpdatedPrediction(locker);
         
         StringPrintStream out;
-        
-        if (m_singletonValueIsTop)
-            out.print("predicting ", SpeculationDump(m_prediction));
-        else if (m_singletonValue)
-            out.print("predicting ", m_singletonValue);
-        
+        out.print("predicting ", SpeculationDump(m_prediction));
         return out.toCString();
     }
     
     void dump(PrintStream& out)
     {
         out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction));
-        out.printf(", value = ");
-        if (m_singletonValueIsTop)
-            out.printf("TOP");
-        else
-            out.print(m_singletonValue);
         bool first = true;
         for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
             JSValue value = JSValue::decode(m_buckets[i]);
@@ -150,7 +138,7 @@
     
     // Updates the prediction and returns the new one. Never call this from any thread
     // that isn't executing the code.
-    SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker&, HeapOperation operation = NoOperation)
+    SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker&)
     {
         for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
             JSValue value = JSValue::decode(m_buckets[i]);
@@ -160,23 +148,9 @@
             m_numberOfSamplesInPrediction++;
             mergeSpeculation(m_prediction, speculationFromValue(value));
             
-            if (!m_singletonValueIsTop && !!value) {
-                if (!m_singletonValue)
-                    m_singletonValue = value;
-                else if (m_singletonValue != value)
-                    m_singletonValueIsTop = true;
-            }
-            
             m_buckets[i] = JSValue::encode(JSValue());
         }
         
-        if (operation == Collection
-            && !m_singletonValueIsTop
-            && !!m_singletonValue
-            && m_singletonValue.isCell()
-            && !Heap::isMarked(m_singletonValue.asCell()))
-            m_singletonValueIsTop = true;
-            
         return m_prediction;
     }
     
@@ -185,9 +159,6 @@
     SpeculatedType m_prediction;
     unsigned m_numberOfSamplesInPrediction;
     
-    bool m_singletonValueIsTop;
-    JSValue m_singletonValue;
-
     EncodedJSValue m_buckets[totalNumberOfBuckets];
 };