DFG should not emit PutByVal hole case unless it has to
https://bugs.webkit.org/show_bug.cgi?id=97080

Reviewed by Geoffrey Garen.

This causes us to generate less code for typical PutByVal's. But if profiling tells us
that the hole case is being hit, we generate the same code as we would have generated
before. This seems like a slight speed-up across the board.

* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::store8):
(MacroAssemblerARMv7):
* assembler/MacroAssemblerX86.h:
(MacroAssemblerX86):
(JSC::MacroAssemblerX86::store8):
* assembler/MacroAssemblerX86_64.h:
(MacroAssemblerX86_64):
(JSC::MacroAssemblerX86_64::store8):
* assembler/X86Assembler.h:
(X86Assembler):
(JSC::X86Assembler::movb_i8m):
* bytecode/ArrayProfile.h:
(JSC::ArrayProfile::ArrayProfile):
(JSC::ArrayProfile::addressOfMayStoreToHole):
(JSC::ArrayProfile::mayStoreToHole):
(ArrayProfile):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::fromObserved):
(JSC::DFG::modeAlreadyChecked):
(JSC::DFG::modeToString):
* dfg/DFGArrayMode.h:
(DFG):
(JSC::DFG::mayStoreToHole):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JIT.h:
(JIT):
* jit/JITInlineMethods.h:
(JSC::JIT::emitArrayProfileStoreToHoleSpecialCase):
(JSC):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_put_by_val):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_put_by_val):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@129045 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h
index cc25864..3b462ea 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.h
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h
@@ -54,6 +54,7 @@
         , m_lastSeenStructure(0)
         , m_expectedStructure(0)
         , m_structureIsPolymorphic(false)
+        , m_mayStoreToHole(false)
         , m_mayInterceptIndexedAccesses(false)
         , m_observedArrayModes(0)
     {
@@ -64,6 +65,7 @@
         , m_lastSeenStructure(0)
         , m_expectedStructure(0)
         , m_structureIsPolymorphic(false)
+        , m_mayStoreToHole(false)
         , m_mayInterceptIndexedAccesses(false)
         , m_observedArrayModes(0)
     {
@@ -73,6 +75,7 @@
     
     Structure** addressOfLastSeenStructure() { return &m_lastSeenStructure; }
     ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
+    bool* addressOfMayStoreToHole() { return &m_mayStoreToHole; }
     
     void observeStructure(Structure* structure)
     {
@@ -93,6 +96,8 @@
     ArrayModes observedArrayModes() const { return m_observedArrayModes; }
     bool mayInterceptIndexedAccesses() const { return m_mayInterceptIndexedAccesses; }
     
+    bool mayStoreToHole() const { return m_mayStoreToHole; }
+    
 private:
     friend class LLIntOffsetsExtractor;
     
@@ -100,6 +105,7 @@
     Structure* m_lastSeenStructure;
     Structure* m_expectedStructure;
     bool m_structureIsPolymorphic;
+    bool m_mayStoreToHole; // This flag may become overloaded to indicate other special cases that were encountered during array access, as it depends on indexing type. Since we currently have basically just one indexing type (two variants of ArrayStorage), this flag for now just means exactly what its name implies.
     bool m_mayInterceptIndexedAccesses;
     ArrayModes m_observedArrayModes;
 };