FTL should generate a unique OSR exit for each duplicated OSR exit stackmap intrinsic.
https://bugs.webkit.org/show_bug.cgi?id=149970

Reviewed by Filip Pizlo.

When we lower DFG to LLVM, we generate a stackmap intrnsic for OSR 
exits. We also recorded the OSR exit inside FTL::JITCode during lowering.
This stackmap intrinsic may be duplicated or even removed by LLVM.
When the stackmap intrinsic is duplicated, we used to generate just
a single OSR exit data structure. Then, when we compiled an OSR exit, we 
would look for the first record in the record list that had the same stackmap ID
as what the OSR exit data structure had. We did this even when the OSR exit
stackmap intrinsic was duplicated. This would lead us to grab the wrong FTL::StackMaps::Record.

Now, each OSR exit knows exactly which FTL::StackMaps::Record it corresponds to.
We accomplish this by having an OSRExitDescriptor that is recorded during
lowering. Each descriptor may be referenced my zero, one, or more OSRExits.
Now, no more than one stackmap intrinsic corresponds to the same index inside 
JITCode's OSRExit Vector. Also, each OSRExit jump now jumps to a code location.

* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLJITCode.cpp:
(JSC::FTL::JITCode::validateReferences):
(JSC::FTL::JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite):
* ftl/FTLJITCode.h:
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeFunction):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::DFG::LowerDFGToLLVM::compileIsUndefined):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::DFG::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::DFG::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::DFG::LowerDFGToLLVM::callStackmap):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
(JSC::FTL::OSRExitDescriptor::validateReferences):
(JSC::FTL::OSRExit::OSRExit):
(JSC::FTL::OSRExit::codeLocationForRepatch):
(JSC::FTL::OSRExit::validateReferences): Deleted.
* ftl/FTLOSRExit.h:
(JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
* ftl/FTLOSRExitCompilationInfo.h:
(JSC::FTL::OSRExitCompilationInfo::OSRExitCompilationInfo):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
(JSC::FTL::compileFTLOSRExit):
* ftl/FTLStackMaps.cpp:
(JSC::FTL::StackMaps::computeRecordMap):
* ftl/FTLStackMaps.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@191313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ftl/FTLOSRExit.cpp b/Source/JavaScriptCore/ftl/FTLOSRExit.cpp
index afa0d53..0b682282 100644
--- a/Source/JavaScriptCore/ftl/FTLOSRExit.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOSRExit.cpp
@@ -40,16 +40,35 @@
 
 using namespace DFG;
 
-OSRExit::OSRExit(
+OSRExitDescriptor::OSRExitDescriptor(
     ExitKind exitKind, DataFormat profileDataFormat,
     MethodOfGettingAValueProfile valueProfile, CodeOrigin codeOrigin,
     CodeOrigin originForProfile, unsigned numberOfArguments,
     unsigned numberOfLocals)
-    : OSRExitBase(exitKind, codeOrigin, originForProfile)
+    : m_kind(exitKind)
+    , m_codeOrigin(codeOrigin)
+    , m_codeOriginForExitProfile(originForProfile)
     , m_profileDataFormat(profileDataFormat)
     , m_valueProfile(valueProfile)
-    , m_patchableCodeOffset(0)
     , m_values(numberOfArguments, numberOfLocals)
+    , m_isInvalidationPoint(false)
+{
+}
+
+void OSRExitDescriptor::validateReferences(const TrackedReferences& trackedReferences)
+{
+    for (unsigned i = m_values.size(); i--;)
+        m_values[i].validateReferences(trackedReferences);
+    
+    for (ExitTimeObjectMaterialization* materialization : m_materializations)
+        materialization->validateReferences(trackedReferences);
+}
+
+
+OSRExit::OSRExit(OSRExitDescriptor& descriptor, uint32_t stackmapRecordIndex)
+    : OSRExitBase(descriptor.m_kind, descriptor.m_codeOrigin, descriptor.m_codeOriginForExitProfile)
+    , m_descriptor(descriptor)
+    , m_stackmapRecordIndex(stackmapRecordIndex)
 {
 }
 
@@ -61,15 +80,6 @@
         m_patchableCodeOffset);
 }
 
-void OSRExit::validateReferences(const TrackedReferences& trackedReferences)
-{
-    for (unsigned i = m_values.size(); i--;)
-        m_values[i].validateReferences(trackedReferences);
-    
-    for (ExitTimeObjectMaterialization* materialization : m_materializations)
-        materialization->validateReferences(trackedReferences);
-}
-
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)