fourthTier: FTL shouldn't use the LLVM global context, and should instead create...
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:00:48 +0000 (04:00 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:00:48 +0000 (04:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=116631

Reviewed by Mark Hahnenberg.

In the future we might want to share contexts for multiple compilations, but for
now using one context per compilation is a progression over just constantly using
the global context.

* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThread):
(DFG):
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPlan.h:
* ftl/FTLAbbreviatedTypes.h:
(FTL):
* ftl/FTLAbbreviations.h:
(JSC::FTL::voidType):
(JSC::FTL::int1Type):
(JSC::FTL::int8Type):
(JSC::FTL::int32Type):
(JSC::FTL::int64Type):
(JSC::FTL::intPtrType):
(JSC::FTL::doubleType):
(JSC::FTL::structType):
(JSC::FTL::mdKindID):
(JSC::FTL::mdString):
(JSC::FTL::mdNode):
(JSC::FTL::appendBasicBlock):
(JSC::FTL::insertBasicBlock):
* ftl/FTLAbstractHeap.cpp:
(JSC::FTL::AbstractHeap::tbaaMetadataSlow):
(JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
(JSC::FTL::NumberedAbstractHeap::NumberedAbstractHeap):
(JSC::FTL::AbsoluteAbstractHeap::AbsoluteAbstractHeap):
* ftl/FTLAbstractHeap.h:
(IndexedAbstractHeap):
(NumberedAbstractHeap):
(AbsoluteAbstractHeap):
* ftl/FTLAbstractHeapRepository.cpp:
(JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
* ftl/FTLAbstractHeapRepository.h:
(AbstractHeapRepository):
* ftl/FTLCommonValues.cpp:
(JSC::FTL::CommonValues::CommonValues):
* ftl/FTLCommonValues.h:
(CommonValues):
* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateCodeSection):
* ftl/FTLIntrinsicRepository.cpp:
(JSC::FTL::IntrinsicRepository::IntrinsicRepository):
* ftl/FTLIntrinsicRepository.h:
(FTL):
(IntrinsicRepository):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::lower):
* ftl/FTLOutput.cpp:
(JSC::FTL::Output::Output):
* ftl/FTLOutput.h:
(Output):
(JSC::FTL::Output::newBlock):
* ftl/FTLState.cpp:
(JSC::FTL::State::State):
(JSC::FTL::State::~State):
(FTL):
* ftl/FTLState.h:
(State):
* runtime/Options.h:
(JSC):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153174 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/dfg/DFGPlan.h
Source/JavaScriptCore/ftl/FTLAbbreviatedTypes.h
Source/JavaScriptCore/ftl/FTLAbbreviations.h
Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp
Source/JavaScriptCore/ftl/FTLAbstractHeap.h
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
Source/JavaScriptCore/ftl/FTLCommonValues.cpp
Source/JavaScriptCore/ftl/FTLCommonValues.h
Source/JavaScriptCore/ftl/FTLCompile.cpp
Source/JavaScriptCore/ftl/FTLIntrinsicRepository.cpp
Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
Source/JavaScriptCore/ftl/FTLOutput.cpp
Source/JavaScriptCore/ftl/FTLOutput.h
Source/JavaScriptCore/ftl/FTLState.cpp
Source/JavaScriptCore/ftl/FTLState.h
Source/JavaScriptCore/runtime/Options.h

index 1ac3496..cee0fec 100644 (file)
@@ -1,3 +1,76 @@
+2013-05-22  Filip Pizlo  <fpizlo@apple.com>
+
+        fourthTier: FTL shouldn't use the LLVM global context, and should instead create its own context for each compilation
+        https://bugs.webkit.org/show_bug.cgi?id=116631
+
+        Reviewed by Mark Hahnenberg.
+        
+        In the future we might want to share contexts for multiple compilations, but for
+        now using one context per compilation is a progression over just constantly using
+        the global context.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThread):
+        (DFG):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPlan.h:
+        * ftl/FTLAbbreviatedTypes.h:
+        (FTL):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::voidType):
+        (JSC::FTL::int1Type):
+        (JSC::FTL::int8Type):
+        (JSC::FTL::int32Type):
+        (JSC::FTL::int64Type):
+        (JSC::FTL::intPtrType):
+        (JSC::FTL::doubleType):
+        (JSC::FTL::structType):
+        (JSC::FTL::mdKindID):
+        (JSC::FTL::mdString):
+        (JSC::FTL::mdNode):
+        (JSC::FTL::appendBasicBlock):
+        (JSC::FTL::insertBasicBlock):
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::AbstractHeap::tbaaMetadataSlow):
+        (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
+        (JSC::FTL::NumberedAbstractHeap::NumberedAbstractHeap):
+        (JSC::FTL::AbsoluteAbstractHeap::AbsoluteAbstractHeap):
+        * ftl/FTLAbstractHeap.h:
+        (IndexedAbstractHeap):
+        (NumberedAbstractHeap):
+        (AbsoluteAbstractHeap):
+        * ftl/FTLAbstractHeapRepository.cpp:
+        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
+        * ftl/FTLAbstractHeapRepository.h:
+        (AbstractHeapRepository):
+        * ftl/FTLCommonValues.cpp:
+        (JSC::FTL::CommonValues::CommonValues):
+        * ftl/FTLCommonValues.h:
+        (CommonValues):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateCodeSection):
+        * ftl/FTLIntrinsicRepository.cpp:
+        (JSC::FTL::IntrinsicRepository::IntrinsicRepository):
+        * ftl/FTLIntrinsicRepository.h:
+        (FTL):
+        (IntrinsicRepository):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        * ftl/FTLOutput.cpp:
+        (JSC::FTL::Output::Output):
+        * ftl/FTLOutput.h:
+        (Output):
+        (JSC::FTL::Output::newBlock):
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::State):
+        (JSC::FTL::State::~State):
+        (FTL):
+        * ftl/FTLState.h:
+        (State):
+        * runtime/Options.h:
+        (JSC):
+
 2013-05-18  Filip Pizlo  <fpizlo@apple.com>
 
         FTL should force LLVM to use our own JIT memory allocator, and we shouldn't have to keep around an LLVMExecutionEngineRef to keep code alive
index 8f89ad1..332c1b6 100644 (file)
@@ -52,6 +52,7 @@
 #include "FTLLowerDFGToLLVM.h"
 #include "FTLState.h"
 #include "Operations.h"
+#include <wtf/CurrentTime.h>
 
 namespace JSC { namespace DFG {
 
@@ -88,17 +89,44 @@ Plan::~Plan()
 
 void Plan::compileInThread(LongLivedState& longLivedState)
 {
+    double before = 0;
+    if (Options::reportCompileTimes())
+        before = currentTimeMS();
+    
     SamplingRegion samplingRegion("DFG Compilation (Plan)");
     CompilationScope compilationScope;
 
     if (logCompilationChanges())
         dataLog("DFG(Plan) compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n");
 
+    CompilationPath path = compileInThreadImpl(longLivedState);
+
+    RELEASE_ASSERT(finalizer);
+    
+    if (Options::reportCompileTimes()) {
+        const char* pathName;
+        switch (path) {
+        case FailPath:
+            pathName = "N/A (fail)";
+            break;
+        case DFGPath:
+            pathName = "DFG";
+            break;
+        case FTLPath:
+            pathName = "FTL";
+            break;
+        }
+        dataLog("Compiled ", *codeBlock, " with ", pathName, " in ", currentTimeMS() - before, " ms.\n");
+    }
+}
+
+Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
+{
     Graph dfg(vm, *this, longLivedState);
     
     if (!parse(dfg)) {
         finalizer = adoptPtr(new FailedFinalizer(*this));
-        return;
+        return FailPath;
     }
     
     // By this point the DFG bytecode parser will have potentially mutated various tables
@@ -151,7 +179,7 @@ void Plan::compileInThread(LongLivedState& longLivedState)
         FTL::lowerDFGToLLVM(state);
         FTL::compile(state);
         FTL::link(state);
-        return;
+        return FTLPath;
     }
 #endif // ENABLE(FTL_JIT)
     
@@ -169,7 +197,7 @@ void Plan::compileInThread(LongLivedState& longLivedState)
         dataFlowJIT.link();
     }
     
-    ASSERT(finalizer);
+    return DFGPath;
 }
 
 bool Plan::isStillValid()
index 7a71823..b9d4b66 100644 (file)
@@ -79,6 +79,9 @@ struct Plan : public ThreadSafeRefCounted<Plan> {
     bool isCompiled;
 
 private:
+    enum CompilationPath { FailPath, DFGPath, FTLPath };
+    CompilationPath compileInThreadImpl(LongLivedState&);
+    
     bool isStillValid();
     void reallyAdd();
 };
index 1d45986..7c44831 100644 (file)
@@ -37,10 +37,11 @@ namespace JSC { namespace FTL {
 typedef LLVMBasicBlockRef LBasicBlock;
 typedef LLVMBuilderRef LBuilder;
 typedef LLVMCallConv LCallConv;
+typedef LLVMContextRef LContext;
 typedef LLVMIntPredicate LIntPredicate;
-typedef LLVMRealPredicate LRealPredicate;
 typedef LLVMLinkage LLinkage;
 typedef LLVMModuleRef LModule;
+typedef LLVMRealPredicate LRealPredicate;
 typedef LLVMTypeRef LType;
 typedef LLVMValueRef LValue;
 
index 1b452bd..8e2881c 100644 (file)
@@ -44,33 +44,33 @@ namespace JSC { namespace FTL {
 #error "The FTL backend assumes that pointers are 64-bit."
 #endif
 
-static inline LType voidType() { return LLVMVoidType(); }
-static inline LType int1Type() { return LLVMInt1Type(); }
-static inline LType int8Type() { return LLVMInt8Type(); }
-static inline LType int32Type() { return LLVMInt32Type(); }
-static inline LType int64Type() { return LLVMInt64Type(); }
-static inline LType intPtrType() { return LLVMInt64Type(); }
-static inline LType doubleType() { return LLVMDoubleType(); }
+static inline LType voidType(LContext context) { return LLVMVoidTypeInContext(context); }
+static inline LType int1Type(LContext context) { return LLVMInt1TypeInContext(context); }
+static inline LType int8Type(LContext context) { return LLVMInt8TypeInContext(context); }
+static inline LType int32Type(LContext context) { return LLVMInt32TypeInContext(context); }
+static inline LType int64Type(LContext context) { return LLVMInt64TypeInContext(context); }
+static inline LType intPtrType(LContext context) { return LLVMInt64TypeInContext(context); }
+static inline LType doubleType(LContext context) { return LLVMDoubleTypeInContext(context); }
 
 static inline LType pointerType(LType type) { return LLVMPointerType(type, 0); }
 
 enum PackingMode { NotPacked, Packed };
-static inline LType structType(LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
 {
-    return LLVMStructType(elementTypes, elementCount, packing == Packed);
+    return LLVMStructTypeInContext(context, elementTypes, elementCount, packing == Packed);
 }
-static inline LType structType(PackingMode packing = NotPacked)
+static inline LType structType(LContext context, PackingMode packing = NotPacked)
 {
-    return structType(0, 0, packing);
+    return structType(context, 0, 0, packing);
 }
-static inline LType structType(LType element1, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType element1, PackingMode packing = NotPacked)
 {
-    return structType(&element1, 1, packing);
+    return structType(context, &element1, 1, packing);
 }
-static inline LType structType(LType element1, LType element2, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType element1, LType element2, PackingMode packing = NotPacked)
 {
     LType elements[] = { element1, element2 };
-    return structType(elements, 2, packing);
+    return structType(context, elements, 2, packing);
 }
 
 enum Variadicity { NotVariadic, Variadic };
@@ -99,16 +99,16 @@ static inline LType functionType(LType returnType, LType param1, LType param2, V
 
 static inline LType typeOf(LValue value) { return LLVMTypeOf(value); }
 
-static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); }
-static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); }
-static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); }
-static inline LValue mdNode(LValue* args, unsigned numArgs) { return LLVMMDNode(args, numArgs); }
-static inline LValue mdNode() { return mdNode(0, 0); }
-static inline LValue mdNode(LValue arg1) { return mdNode(&arg1, 1); }
-static inline LValue mdNode(LValue arg1, LValue arg2)
+static inline unsigned mdKindID(LContext context, const char* string) { return LLVMGetMDKindIDInContext(context, string, strlen(string)); }
+static inline LValue mdString(LContext context, const char* string, unsigned length) { return LLVMMDStringInContext(context, string, length); }
+static inline LValue mdString(LContext context, const char* string) { return mdString(context, string, strlen(string)); }
+static inline LValue mdNode(LContext context, LValue* args, unsigned numArgs) { return LLVMMDNodeInContext(context, args, numArgs); }
+static inline LValue mdNode(LContext context) { return mdNode(context, 0, 0); }
+static inline LValue mdNode(LContext context, LValue arg1) { return mdNode(context, &arg1, 1); }
+static inline LValue mdNode(LContext context, LValue arg1, LValue arg2)
 {
     LValue args[] = { arg1, arg2 };
-    return mdNode(args, 2);
+    return mdNode(context, args, 2);
 }
 
 static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { LLVMSetMetadata(instruction, kind, metadata); }
@@ -132,8 +132,8 @@ static inline LValue constReal(LType type, double value) { return LLVMConstReal(
 static inline LValue constIntToPtr(LValue value, LType type) { return LLVMConstIntToPtr(value, type); }
 static inline LValue constBitCast(LValue value, LType type) { return LLVMConstBitCast(value, type); }
 
-static inline LBasicBlock appendBasicBlock(LValue function, const char* name = "") { return LLVMAppendBasicBlock(function, name); }
-static inline LBasicBlock insertBasicBlock(LBasicBlock beforeBasicBlock, const char* name = "") { return LLVMInsertBasicBlock(beforeBasicBlock, name); }
+static inline LBasicBlock appendBasicBlock(LContext context, LValue function, const char* name = "") { return LLVMAppendBasicBlockInContext(context, function, name); }
+static inline LBasicBlock insertBasicBlock(LContext context, LBasicBlock beforeBasicBlock, const char* name = "") { return LLVMInsertBasicBlockInContext(context, beforeBasicBlock, name); }
 
 static inline LValue buildPhi(LBuilder builder, LType type) { return LLVMBuildPhi(builder, type, ""); }
 static inline void addIncoming(LValue phi, const LValue* values, const LBasicBlock* blocks, unsigned numPredecessors)
index fbe5e63..7bd159d 100644 (file)
@@ -39,7 +39,10 @@ namespace JSC { namespace FTL {
 
 LValue AbstractHeap::tbaaMetadataSlow(const AbstractHeapRepository& repository) const
 {
-    m_tbaaMetadata = mdNode(mdString(m_heapName), m_parent->tbaaMetadata(repository));
+    m_tbaaMetadata = mdNode(
+        repository.m_context,
+        mdString(repository.m_context, m_heapName),
+        m_parent->tbaaMetadata(repository));
     return m_tbaaMetadata;
 }
 
@@ -50,7 +53,7 @@ void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRep
     setMetadata(instruction, repository.m_tbaaKind, tbaaMetadata(repository));
 }
 
-IndexedAbstractHeap::IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, size_t elementSize)
+IndexedAbstractHeap::IndexedAbstractHeap(LContext context, AbstractHeap* parent, const char* heapName, size_t elementSize)
     : m_heapForAnyIndex(parent, heapName)
     , m_heapNameLength(strlen(heapName))
     , m_elementSize(elementSize)
@@ -62,14 +65,14 @@ IndexedAbstractHeap::IndexedAbstractHeap(AbstractHeap* parent, const char* heapN
     for (unsigned i = 0; i < 4; ++i) {
         if ((1 << i) == m_elementSize) {
             if (i)
-                m_scaleTerm = constInt(intPtrType(), i, ZeroExtend);
+                m_scaleTerm = constInt(intPtrType(context), i, ZeroExtend);
             m_canShift = true;
             break;
         }
     }
     
     if (!m_canShift)
-        m_scaleTerm = constInt(intPtrType(), m_elementSize, ZeroExtend);
+        m_scaleTerm = constInt(intPtrType(context), m_elementSize, ZeroExtend);
 }
 
 IndexedAbstractHeap::~IndexedAbstractHeap()
@@ -174,8 +177,9 @@ void IndexedAbstractHeap::initialize(AbstractField& field, ptrdiff_t signedIndex
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-NumberedAbstractHeap::NumberedAbstractHeap(AbstractHeap* heap, const char* heapName)
-    : m_indexedHeap(heap, heapName, 1)
+NumberedAbstractHeap::NumberedAbstractHeap(
+    LContext context, AbstractHeap* heap, const char* heapName)
+    : m_indexedHeap(context, heap, heapName, 1)
 {
 }
 
@@ -183,8 +187,9 @@ NumberedAbstractHeap::~NumberedAbstractHeap()
 {
 }
 
-AbsoluteAbstractHeap::AbsoluteAbstractHeap(AbstractHeap* heap, const char* heapName)
-    : m_indexedHeap(heap, heapName, 1)
+AbsoluteAbstractHeap::AbsoluteAbstractHeap(
+    LContext context, AbstractHeap* heap, const char* heapName)
+    : m_indexedHeap(context, heap, heapName, 1)
 {
 }
 
index a0dbdf5..59f87f9 100644 (file)
@@ -139,7 +139,7 @@ private:
 
 class IndexedAbstractHeap {
 public:
-    IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, size_t elementSize);
+    IndexedAbstractHeap(LContext, AbstractHeap* parent, const char* heapName, size_t elementSize);
     ~IndexedAbstractHeap();
     
     const AbstractHeap& atAnyIndex() const { return m_heapForAnyIndex; }
@@ -190,7 +190,7 @@ private:
 
 class NumberedAbstractHeap {
 public:
-    NumberedAbstractHeap(AbstractHeap* parent, const char* heapName);
+    NumberedAbstractHeap(LContext, AbstractHeap* parent, const char* heapName);
     ~NumberedAbstractHeap();
     
     const AbstractHeap& atAnyNumber() const { return m_indexedHeap.atAnyIndex(); }
@@ -207,7 +207,7 @@ private:
 
 class AbsoluteAbstractHeap {
 public:
-    AbsoluteAbstractHeap(AbstractHeap* parent, const char* heapName);
+    AbsoluteAbstractHeap(LContext, AbstractHeap* parent, const char* heapName);
     ~AbsoluteAbstractHeap();
     
     const AbstractHeap& atAnyAddress() const { return m_indexedHeap.atAnyIndex(); }
index d66534a..114eb19 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace JSC { namespace FTL {
 
-AbstractHeapRepository::AbstractHeapRepository()
+AbstractHeapRepository::AbstractHeapRepository(LContext context)
     : root(0, "jscRoot")
 
 #define ABSTRACT_HEAP_INITIALIZATION(name) , name(&root, #name)
@@ -43,18 +43,19 @@ AbstractHeapRepository::AbstractHeapRepository()
     FOR_EACH_ABSTRACT_FIELD(ABSTRACT_FIELD_INITIALIZATION)
 #undef ABSTRACT_FIELD_INITIALIZATION
     
-#define INDEXED_ABSTRACT_HEAP_INITIALIZATION(name, size) , name(&root, #name, size)
+#define INDEXED_ABSTRACT_HEAP_INITIALIZATION(name, size) , name(context, &root, #name, size)
     FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_INITIALIZATION)
 #undef INDEXED_ABSTRACT_HEAP_INITIALIZATION
     
-#define NUMBERED_ABSTRACT_HEAP_INITIALIZATION(name) , name(&root, #name)
+#define NUMBERED_ABSTRACT_HEAP_INITIALIZATION(name) , name(context, &root, #name)
     FOR_EACH_NUMBERED_ABSTRACT_HEAP(NUMBERED_ABSTRACT_HEAP_INITIALIZATION)
 #undef NUMBERED_ABSTRACT_HEAP_INITIALIZATION
 
-    , absolute(&root, "absolute")
-    , m_tbaaKind(mdKindID("tbaa"))
+    , absolute(context, &root, "absolute")
+    , m_context(context)
+    , m_tbaaKind(mdKindID(m_context, "tbaa"))
 {
-    root.m_tbaaMetadata = mdNode(mdString(root.m_heapName));
+    root.m_tbaaMetadata = mdNode(m_context, mdString(m_context, root.m_heapName));
     
     RELEASE_ASSERT(m_tbaaKind);
     RELEASE_ASSERT(root.m_tbaaMetadata);
index 445e15d..e5d56ad 100644 (file)
@@ -61,7 +61,7 @@ namespace JSC { namespace FTL {
 class AbstractHeapRepository {
     WTF_MAKE_NONCOPYABLE(AbstractHeapRepository);
 public:
-    AbstractHeapRepository();
+    AbstractHeapRepository(LContext);
     ~AbstractHeapRepository();
     
     AbstractHeap root;
@@ -87,6 +87,7 @@ public:
 private:
     friend class AbstractHeap;
     
+    LContext m_context;
     unsigned m_tbaaKind;
 };
 
index 5b97b2c..8ee0301 100644 (file)
 
 namespace JSC { namespace FTL {
 
-CommonValues::CommonValues()
-    : voidType(FTL::voidType())
-    , boolean(int1Type())
-    , int8(int8Type())
-    , int32(int32Type())
-    , int64(int64Type())
-    , intPtr(intPtrType())
-    , doubleType(FTL::doubleType())
+CommonValues::CommonValues(LContext context)
+    : voidType(FTL::voidType(context))
+    , boolean(int1Type(context))
+    , int8(int8Type(context))
+    , int32(int32Type(context))
+    , int64(int64Type(context))
+    , intPtr(intPtrType(context))
+    , doubleType(FTL::doubleType(context))
     , ref8(pointerType(int8))
     , ref32(pointerType(int32))
     , ref64(pointerType(int64))
@@ -56,6 +56,7 @@ CommonValues::CommonValues()
     , intPtrEight(constInt(intPtr, 8, SignExtend))
     , intPtrPtr(constInt(intPtr, sizeof(void*), SignExtend))
     , doubleZero(constReal(doubleType, 0))
+    , m_context(context)
     , m_module(0)
 {
 }
index ae6ef36..9e3c757 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC { namespace FTL {
 
 class CommonValues {
 public:
-    CommonValues();
+    CommonValues(LContext context);
     
     void initialize(LModule module)
     {
@@ -69,6 +69,7 @@ public:
     const LValue intPtrPtr;
     const LValue doubleZero;
     
+    LContext const m_context;
     LModule m_module;
 };
 
index f25a0eb..75d3e72 100644 (file)
@@ -47,7 +47,7 @@ static uint8_t* mmAllocateCodeSection(
     
     State& state = *static_cast<State*>(opaqueState);
     
-    ASSERT(alignment <= jitAllocationGranule);
+    RELEASE_ASSERT(alignment <= jitAllocationGranule);
     
     RefPtr<ExecutableMemoryHandle> result =
         state.graph.m_vm.executableAllocator.allocate(
index 5797a7a..e85e740 100644 (file)
@@ -30,8 +30,8 @@
 
 namespace JSC { namespace FTL {
 
-IntrinsicRepository::IntrinsicRepository()
-    : CommonValues() // Call this explicitly to make the following macro magic work.
+IntrinsicRepository::IntrinsicRepository(LContext context)
+    : CommonValues(context)
 #define INTRINSIC_INITIALIZATION(ourName, llvmName, type) , m_##ourName(0)
     FOR_EACH_FTL_INTRINSIC(INTRINSIC_INITIALIZATION)
 #undef INTRINSIC_INITIALIZATION
index 333227f..1ba5cb2 100644 (file)
 namespace JSC { namespace FTL {
 
 #define FOR_EACH_FTL_INTRINSIC(macro) \
-    macro(addWithOverflow32, "llvm.sadd.with.overflow.i32", functionType(structType(int32, boolean), int32, int32)) \
-    macro(subWithOverflow32, "llvm.ssub.with.overflow.i32", functionType(structType(int32, boolean), int32, int32)) \
-    macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(int32, boolean), int32, int32))
+    macro(addWithOverflow32, "llvm.sadd.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
+    macro(subWithOverflow32, "llvm.ssub.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
+    macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32))
 
 class IntrinsicRepository : public CommonValues {
 public:
-    IntrinsicRepository();
+    IntrinsicRepository(LContext);
     
 #define INTRINSIC_GETTER(ourName, llvmName, type) \
     LValue ourName##Intrinsic() {                 \
index a711d6c..a36c6aa 100644 (file)
@@ -59,6 +59,8 @@ public:
     LowerDFGToLLVM(State& state)
         : m_graph(state.graph)
         , m_ftlState(state)
+        , m_heaps(state.context)
+        , m_out(state.context)
         , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
         , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
         , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
@@ -73,7 +75,8 @@ public:
     void lower()
     {
         CString name = toCString(codeBlock()->hash());
-        m_ftlState.module = LLVMModuleCreateWithName(name.data());
+        m_ftlState.module =
+            LLVMModuleCreateWithNameInContext(name.data(), m_ftlState.context);
         
         m_ftlState.function = addFunction(
             m_ftlState.module, name.data(), functionType(m_out.int64, m_out.intPtr));
@@ -81,7 +84,7 @@ public:
         
         m_out.initialize(m_ftlState.module, m_ftlState.function, m_heaps);
         
-        m_prologue = appendBasicBlock(m_ftlState.function);
+        m_prologue = appendBasicBlock(m_ftlState.context, m_ftlState.function);
         m_out.appendTo(m_prologue);
         for (unsigned index = m_localsBoolean.size(); index--;) {
             m_localsBoolean[index] = buildAlloca(m_out.m_builder, m_out.boolean);
@@ -90,8 +93,8 @@ public:
             m_localsDouble[index] = buildAlloca(m_out.m_builder, m_out.doubleType);
         }
         
-        m_initialization = appendBasicBlock(m_ftlState.function);
-        m_argumentChecks = appendBasicBlock(m_ftlState.function);
+        m_initialization = appendBasicBlock(m_ftlState.context, m_ftlState.function);
+        m_argumentChecks = appendBasicBlock(m_ftlState.context, m_ftlState.function);
 
         m_callFrame = m_out.param(0);
         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
index 39de1f8..f3c3167 100644 (file)
 
 namespace JSC { namespace FTL {
 
-Output::Output()
-    : m_function(0)
+Output::Output(LContext context)
+    : IntrinsicRepository(context)
+    , m_function(0)
     , m_heaps(0)
-    , m_builder(LLVMCreateBuilder())
+    , m_builder(LLVMCreateBuilderInContext(m_context))
     , m_block(0)
     , m_nextBlock(0)
 {
index 7ddac7b..69849b8 100644 (file)
@@ -67,7 +67,7 @@ enum Scale { ScaleOne, ScaleTwo, ScaleFour, ScaleEight, ScalePtr };
 
 class Output : public IntrinsicRepository {
 public:
-    Output();
+    Output(LContext);
     ~Output();
     
     void initialize(LModule module, LValue function, AbstractHeapRepository& heaps)
@@ -99,8 +99,8 @@ public:
     LBasicBlock newBlock(const char* name = "")
     {
         if (!m_nextBlock)
-            return appendBasicBlock(m_function, name);
-        return insertBasicBlock(m_nextBlock, name);
+            return appendBasicBlock(m_context, m_function, name);
+        return insertBasicBlock(m_context, m_nextBlock, name);
     }
     
     LValue param(unsigned index) { return getParam(m_function, index); }
index ab4c2e1..c3174a9 100644 (file)
@@ -37,6 +37,7 @@ using namespace DFG;
 
 State::State(Graph& graph)
     : graph(graph)
+    , context(LLVMContextCreate())
     , module(0)
     , function(0)
     , jitCode(adoptRef(new JITCode()))
@@ -46,6 +47,11 @@ State::State(Graph& graph)
     graph.m_plan.finalizer = adoptPtr(finalizer);
 }
 
+State::~State()
+{
+    LLVMContextDispose(context);
+}
+
 void State::dumpState(const char* when)
 {
     dataLog("LLVM IR for ", CodeBlockWithJITType(graph.m_codeBlock, FTL::JITCode::FTLJIT), " ", when, ":\n");
index 4bf656f..cef0fe3 100644 (file)
@@ -45,10 +45,12 @@ class State {
     
 public:
     State(DFG::Graph& graph);
+    ~State();
     
     // None of these things is owned by State. It is the responsibility of
     // FTL phases to properly manage the lifecycle of the module and function.
     DFG::Graph& graph;
+    LContext context;
     LModule module;
     LValue function;
     RefPtr<JITCode> jitCode;
index 33e6554..1219d37 100644 (file)
@@ -111,6 +111,7 @@ typedef OptionRange optionRange;
     v(bool, validateGraphAtEachPhase, false) \
     v(bool, verboseOSR, false) \
     v(bool, verboseCompilationQueue, false) \
+    v(bool, reportCompileTimes, false) \
     \
     v(bool, useExperimentalFTL, false) \
     v(bool, useFTLTBAA, true) \