Try ripping out inferred types because it might be a performance improvement
https://bugs.webkit.org/show_bug.cgi?id=190906

Reviewed by Yusuke Suzuki.

This patch removes inferred types from JSC. Initial evidence shows that
this might be around a ~1% speedup on Speedometer2 and JetStream2.

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* bytecode/Fits.h:
* bytecode/PutByIdFlags.cpp:
(WTF::printInternal):
* bytecode/PutByIdFlags.h:
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFromLLInt):
(JSC::PutByIdStatus::computeForStubInfo):
(JSC::PutByIdStatus::computeFor):
* bytecode/PutByIdVariant.cpp:
(JSC::PutByIdVariant::operator=):
(JSC::PutByIdVariant::replace):
(JSC::PutByIdVariant::transition):
(JSC::PutByIdVariant::setter):
(JSC::PutByIdVariant::attemptToMerge):
(JSC::PutByIdVariant::dumpInContext const):
* bytecode/PutByIdVariant.h:
(JSC::PutByIdVariant::requiredType const): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::isType const): Deleted.
* dfg/DFGAbstractValue.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleGetByOffset):
(JSC::DFG::ByteCodeParser::handlePutByOffset):
(JSC::DFG::ByteCodeParser::load):
(JSC::DFG::ByteCodeParser::store):
(JSC::DFG::ByteCodeParser::handlePutById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
(JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
* dfg/DFGDesiredInferredType.h: Removed.
* dfg/DFGDesiredWatchpoints.cpp:
(JSC::DFG::DesiredWatchpoints::reallyAdd):
(JSC::DFG::DesiredWatchpoints::areStillValid const):
(JSC::DFG::DesiredWatchpoints::dumpInContext const):
(JSC::DFG::InferredTypeAdaptor::add): Deleted.
* dfg/DFGDesiredWatchpoints.h:
(JSC::DFG::DesiredWatchpoints::isWatched):
(JSC::DFG::InferredTypeAdaptor::hasBeenInvalidated): Deleted.
(JSC::DFG::InferredTypeAdaptor::dumpInContext): Deleted.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::inferredValueForProperty):
(JSC::DFG::Graph::inferredTypeFor): Deleted.
* dfg/DFGGraph.h:
(JSC::DFG::Graph::registerInferredType): Deleted.
(JSC::DFG::Graph::inferredTypeForProperty): Deleted.
* dfg/DFGInferredTypeCheck.cpp: Removed.
* dfg/DFGInferredTypeCheck.h: Removed.
* dfg/DFGNode.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset):
(JSC::FTL::DFG::LowerDFGToB3::checkInferredType): Deleted.
* generator/DSL.rb:
* heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::branchIfNotType): Deleted.
* jit/AssemblyHelpers.h:
* jit/Repatch.cpp:
(JSC::tryCachePutByID):
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/InferredStructure.cpp:
(JSC::InferredStructure::InferredStructure): Deleted.
* runtime/InferredStructure.h:
(): Deleted.
* runtime/InferredStructureWatchpoint.cpp:
(JSC::InferredStructureWatchpoint::fireInternal): Deleted.
* runtime/InferredType.cpp: Removed.
* runtime/InferredType.h: Removed.
* runtime/InferredTypeInlines.h: Removed.
* runtime/InferredTypeTable.cpp: Removed.
* runtime/InferredTypeTable.h: Removed.
* runtime/JSObjectInlines.h:
(JSC::JSObject::putDirectInternal):
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyTable):
(JSC::Structure::addNewPropertyTransition):
(JSC::Structure::removePropertyTransition):
(JSC::Structure::willStoreValueSlow):
(JSC::Structure::visitChildren):
* runtime/Structure.h:
(JSC::PropertyMapEntry::PropertyMapEntry):
* runtime/StructureInlines.h:
(JSC::Structure::get):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@240023 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/AccessCase.cpp b/Source/JavaScriptCore/bytecode/AccessCase.cpp
index 59596b6..9e6ec7b 100644
--- a/Source/JavaScriptCore/bytecode/AccessCase.cpp
+++ b/Source/JavaScriptCore/bytecode/AccessCase.cpp
@@ -1019,14 +1019,6 @@
     }
 
     case Replace: {
-        if (InferredType* type = structure()->inferredTypeFor(ident.impl())) {
-            if (AccessCaseInternal::verbose)
-                dataLog("Have type: ", type->descriptor(), "\n");
-            state.failAndRepatch.append(
-                jit.branchIfNotType(valueRegs, scratchGPR, type->descriptor()));
-        } else if (AccessCaseInternal::verbose)
-            dataLog("Don't have type.\n");
-
         if (isInlineOffset(m_offset)) {
             jit.storeValue(
                 valueRegs,
@@ -1049,14 +1041,6 @@
         // AccessCase::transition() should have returned null if this wasn't true.
         RELEASE_ASSERT(GPRInfo::numberOfRegisters >= 6 || !structure()->outOfLineCapacity() || structure()->outOfLineCapacity() == newStructure()->outOfLineCapacity());
 
-        if (InferredType* type = newStructure()->inferredTypeFor(ident.impl())) {
-            if (AccessCaseInternal::verbose)
-                dataLog("Have type: ", type->descriptor(), "\n");
-            state.failAndRepatch.append(
-                jit.branchIfNotType(valueRegs, scratchGPR, type->descriptor()));
-        } else if (AccessCaseInternal::verbose)
-            dataLog("Don't have type.\n");
-
         // NOTE: This logic is duplicated in AccessCase::doesCalls(). It's important that doesCalls() knows
         // exactly when this would make calls.
         bool allocating = newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity();
diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb
index 3c8b312..19c630d 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb
+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb
@@ -474,11 +474,7 @@
         oldStructure: StructureID,
         offset: unsigned,
         newStructure: StructureID,
-        flags: PutByIdFlags,
         structureChain: WriteBarrierBase[StructureChain],
-    },
-    metadata_initializers: {
-        flags: :flags
     }
 
 op :put_by_id_with_this,
diff --git a/Source/JavaScriptCore/bytecode/Fits.h b/Source/JavaScriptCore/bytecode/Fits.h
index 2626b6a..cefdb4b 100644
--- a/Source/JavaScriptCore/bytecode/Fits.h
+++ b/Source/JavaScriptCore/bytecode/Fits.h
@@ -30,6 +30,7 @@
 #include "Label.h"
 #include "OpcodeSize.h"
 #include "ProfileTypeBytecodeFlag.h"
+#include "PutByIdFlags.h"
 #include "ResultType.h"
 #include "SpecialPointer.h"
 #include "VirtualRegister.h"
diff --git a/Source/JavaScriptCore/bytecode/PutByIdFlags.cpp b/Source/JavaScriptCore/bytecode/PutByIdFlags.cpp
index f280900..c8a4b60 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdFlags.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdFlags.cpp
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "PutByIdFlags.h"
 
-#include "InferredType.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/PrintStream.h>
 #include <wtf/StringPrintStream.h>
@@ -39,11 +38,6 @@
     CommaPrinter comma("|");
     if (flags & PutByIdIsDirect)
         out.print(comma, "IsDirect");
-
-    InferredType::Kind kind = InferredType::kindForFlags(flags);
-    out.print(comma, kind);
-    if (InferredType::hasStructure(kind))
-        out.print(":", bitwise_cast<int32_t>(decodeStructureID(flags)));
 }
 
 } // namespace WTF
diff --git a/Source/JavaScriptCore/bytecode/PutByIdFlags.h b/Source/JavaScriptCore/bytecode/PutByIdFlags.h
index 7decfb2..5c04928 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdFlags.h
+++ b/Source/JavaScriptCore/bytecode/PutByIdFlags.h
@@ -36,60 +36,8 @@
     // checking if the prototype chain has a setter.
     PutByIdIsDirect = 0x1,
     PutByIdPersistentFlagsMask = 0x1,
-
-    // NOTE: The values below must be in sync with what is in LowLevelInterpreter.asm.
-
-    // Determining the required inferred type involves first checking the primary type mask, and then
-    // using that to figure out the meaning of the secondary mask:
-    // switch (flags & PutByIdPrimaryTypeMask) {
-    // case PutByIdPrimaryTypeSecondary:
-    //     switch (flags & PutByIdSecondaryTypeMask) {
-    //     ...
-    //     }
-    //     break;
-    // case PutByIdPrimaryTypeObjectWithStructure:
-    // case PutByIdPrimaryTypeObjectWithStructureOrOther:
-    //     StructureID structureID = decodeStructureID(flags);
-    //     break;
-    // }
-    PutByIdPrimaryTypeMask = 0x6,
-    PutByIdPrimaryTypeSecondary = 0x0, // Need to check the secondary type mask for the type.
-    PutByIdPrimaryTypeObjectWithStructure = 0x2, // Secondary type has structure ID.
-    PutByIdPrimaryTypeObjectWithStructureOrOther = 0x4, // Secondary type has structure ID.
-
-    PutByIdSecondaryTypeMask = -0x8,
-    PutByIdSecondaryTypeBottom = 0x0,
-    PutByIdSecondaryTypeBoolean = 0x8,
-    PutByIdSecondaryTypeOther = 0x10,
-    PutByIdSecondaryTypeInt32 = 0x18,
-    PutByIdSecondaryTypeNumber = 0x20,
-    PutByIdSecondaryTypeString = 0x28,
-    PutByIdSecondaryTypeSymbol = 0x30,
-    PutByIdSecondaryTypeObject = 0x38,
-    PutByIdSecondaryTypeObjectOrOther = 0x40,
-    PutByIdSecondaryTypeTop = 0x48
 };
 
-inline PutByIdFlags encodeStructureID(StructureID id)
-{
-#if USE(JSVALUE64)
-    return static_cast<PutByIdFlags>(static_cast<PutByIdFlags>(id) << 3);
-#else
-    PutByIdFlags result = bitwise_cast<PutByIdFlags>(id);
-    ASSERT(!(result & ~PutByIdSecondaryTypeMask));
-    return result;
-#endif
-}
-
-inline StructureID decodeStructureID(PutByIdFlags flags)
-{
-#if USE(JSVALUE64)
-    return static_cast<StructureID>(flags >> 3);
-#else
-    return bitwise_cast<StructureID>(flags & PutByIdSecondaryTypeMask);
-#endif
-}
-
 } // namespace JSC
 
 namespace WTF {
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
index 02f5231..47545de 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
@@ -52,7 +52,8 @@
     VM& vm = *profiledBlock->vm();
     
     auto instruction = profiledBlock->instructions().at(bytecodeIndex);
-    auto& metadata = instruction->as<OpPutById>().metadata(profiledBlock);
+    auto bytecode = instruction->as<OpPutById>();
+    auto& metadata = bytecode.metadata(profiledBlock);
 
     StructureID structureID = metadata.oldStructure;
     if (!structureID)
@@ -66,7 +67,7 @@
         if (!isValidOffset(offset))
             return PutByIdStatus(NoInformation);
         
-        return PutByIdVariant::replace(structure, offset, structure->inferredTypeDescriptorFor(uid));
+        return PutByIdVariant::replace(structure, offset);
     }
 
     Structure* newStructure = vm.heap.structureIDTable().get(newStructureID);
@@ -78,7 +79,7 @@
         return PutByIdStatus(NoInformation);
     
     ObjectPropertyConditionSet conditionSet;
-    if (!(metadata.flags & PutByIdIsDirect)) {
+    if (!(bytecode.flags & PutByIdIsDirect)) {
         conditionSet =
             generateConditionsForPropertySetterMissConcurrently(
                 vm, profiledBlock->globalObject(), structure, uid);
@@ -87,7 +88,7 @@
     }
     
     return PutByIdVariant::transition(
-        structure, newStructure, conditionSet, offset, newStructure->inferredTypeDescriptorFor(uid));
+        structure, newStructure, conditionSet, offset);
 }
 
 #if ENABLE(JIT)
@@ -142,7 +143,7 @@
             stubInfo->u.byIdSelf.baseObjectStructure->getConcurrently(uid);
         if (isValidOffset(offset)) {
             return PutByIdVariant::replace(
-                stubInfo->u.byIdSelf.baseObjectStructure.get(), offset, InferredType::Top);
+                stubInfo->u.byIdSelf.baseObjectStructure.get(), offset);
         }
         return PutByIdStatus(JSC::slowVersion(summary));
     }
@@ -169,7 +170,7 @@
                 if (!isValidOffset(offset))
                     return PutByIdStatus(JSC::slowVersion(summary));
                 variant = PutByIdVariant::replace(
-                    structure, offset, structure->inferredTypeDescriptorFor(uid));
+                    structure, offset);
                 break;
             }
                 
@@ -182,8 +183,7 @@
                 if (!conditionSet.structuresEnsureValidity())
                     return PutByIdStatus(JSC::slowVersion(summary));
                 variant = PutByIdVariant::transition(
-                    access.structure(), access.newStructure(), conditionSet, offset,
-                    access.newStructure()->inferredTypeDescriptorFor(uid));
+                    access.structure(), access.newStructure(), conditionSet, offset);
                 break;
             }
                 
@@ -315,7 +315,7 @@
             }
 
             PutByIdVariant variant =
-                PutByIdVariant::replace(structure, offset, structure->inferredTypeDescriptorFor(uid));
+                PutByIdVariant::replace(structure, offset);
             if (!result.appendVariant(variant))
                 return PutByIdStatus(TakesSlowPath);
             continue;
@@ -350,8 +350,7 @@
     
         bool didAppend = result.appendVariant(
             PutByIdVariant::transition(
-                structure, transition, conditionSet, offset,
-                transition->inferredTypeDescriptorFor(uid)));
+                structure, transition, conditionSet, offset));
         if (!didAppend)
             return PutByIdStatus(TakesSlowPath);
     }
diff --git a/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp b/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
index c39869d..88dee07 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
@@ -45,7 +45,6 @@
     m_newStructure = other.m_newStructure;
     m_conditionSet = other.m_conditionSet;
     m_offset = other.m_offset;
-    m_requiredType = other.m_requiredType;
     if (other.m_callLinkStatus)
         m_callLinkStatus = std::make_unique<CallLinkStatus>(*other.m_callLinkStatus);
     else
@@ -54,20 +53,18 @@
 }
 
 PutByIdVariant PutByIdVariant::replace(
-    const StructureSet& structure, PropertyOffset offset, const InferredType::Descriptor& requiredType)
+    const StructureSet& structure, PropertyOffset offset)
 {
     PutByIdVariant result;
     result.m_kind = Replace;
     result.m_oldStructure = structure;
     result.m_offset = offset;
-    result.m_requiredType = requiredType;
     return result;
 }
 
 PutByIdVariant PutByIdVariant::transition(
     const StructureSet& oldStructure, Structure* newStructure,
-    const ObjectPropertyConditionSet& conditionSet, PropertyOffset offset,
-    const InferredType::Descriptor& requiredType)
+    const ObjectPropertyConditionSet& conditionSet, PropertyOffset offset)
 {
     PutByIdVariant result;
     result.m_kind = Transition;
@@ -75,7 +72,6 @@
     result.m_newStructure = newStructure;
     result.m_conditionSet = conditionSet;
     result.m_offset = offset;
-    result.m_requiredType = requiredType;
     return result;
 }
 
@@ -90,7 +86,6 @@
     result.m_conditionSet = conditionSet;
     result.m_offset = offset;
     result.m_callLinkStatus = WTFMove(callLinkStatus);
-    result.m_requiredType = InferredType::Top;
     return result;
 }
 
@@ -159,9 +154,6 @@
     if (m_offset != other.m_offset)
         return false;
 
-    if (m_requiredType != other.m_requiredType)
-        return false;
-    
     switch (m_kind) {
     case NotSet:
         RELEASE_ASSERT_NOT_REACHED();
@@ -305,16 +297,14 @@
         
     case Replace:
         out.print(
-            "<Replace: ", inContext(structure(), context), ", offset = ", offset(), ", ",
-            inContext(requiredType(), context), ">");
+            "<Replace: ", inContext(structure(), context), ", offset = ", offset(), ", ", ">");
         return;
         
     case Transition:
         out.print(
             "<Transition: ", inContext(oldStructure(), context), " to ",
             pointerDumpInContext(newStructure(), context), ", [",
-            inContext(m_conditionSet, context), "], offset = ", offset(), ", ",
-            inContext(requiredType(), context), ">");
+            inContext(m_conditionSet, context), "], offset = ", offset(), ", ", ">");
         return;
         
     case Setter:
diff --git a/Source/JavaScriptCore/bytecode/PutByIdVariant.h b/Source/JavaScriptCore/bytecode/PutByIdVariant.h
index 05a3a13..e4f424f 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdVariant.h
+++ b/Source/JavaScriptCore/bytecode/PutByIdVariant.h
@@ -52,11 +52,11 @@
     PutByIdVariant(const PutByIdVariant&);
     PutByIdVariant& operator=(const PutByIdVariant&);
 
-    static PutByIdVariant replace(const StructureSet&, PropertyOffset, const InferredType::Descriptor&);
+    static PutByIdVariant replace(const StructureSet&, PropertyOffset);
     
     static PutByIdVariant transition(
         const StructureSet& oldStructure, Structure* newStructure,
-        const ObjectPropertyConditionSet&, PropertyOffset, const InferredType::Descriptor&);
+        const ObjectPropertyConditionSet&, PropertyOffset);
     
     static PutByIdVariant setter(
         const StructureSet&, PropertyOffset, const ObjectPropertyConditionSet&,
@@ -105,11 +105,6 @@
     
     void fixTransitionToReplaceIfNecessary();
 
-    InferredType::Descriptor requiredType() const
-    {
-        return m_requiredType;
-    }
-
     bool writesStructures() const;
     bool reallocatesStorage() const;
     bool makesCalls() const;
@@ -150,7 +145,6 @@
     Structure* m_newStructure { nullptr };
     ObjectPropertyConditionSet m_conditionSet;
     PropertyOffset m_offset;
-    InferredType::Descriptor m_requiredType;
     std::unique_ptr<CallLinkStatus> m_callLinkStatus;
 };