f25a0eb53180517339526121acf87c7393282e2e
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLCompile.cpp
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "FTLCompile.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "CodeBlockWithJITType.h"
32 #include "DFGCCallHelpers.h"
33 #include "DFGCommon.h"
34 #include "FTLJITCode.h"
35 #include "FTLLLVMHeaders.h"
36 #include "JITStubs.h"
37 #include "LinkBuffer.h"
38
39 namespace JSC { namespace FTL {
40
41 using namespace DFG;
42
43 static uint8_t* mmAllocateCodeSection(
44     void* opaqueState, uintptr_t size, unsigned alignment, unsigned sectionID)
45 {
46     UNUSED_PARAM(sectionID);
47     
48     State& state = *static_cast<State*>(opaqueState);
49     
50     ASSERT(alignment <= jitAllocationGranule);
51     
52     RefPtr<ExecutableMemoryHandle> result =
53         state.graph.m_vm.executableAllocator.allocate(
54             state.graph.m_vm, size, state.graph.m_codeBlock, JITCompilationMustSucceed);
55     
56     state.jitCode->addHandle(result);
57     
58     return static_cast<uint8_t*>(result->start());
59 }
60
61 static uint8_t* mmAllocateDataSection(
62     void* opaqueState, uintptr_t size, unsigned alignment, unsigned sectionID,
63     LLVMBool isReadOnly)
64 {
65     // FIXME: fourthTier: FTL memory allocator should be able to allocate data
66     // sections in non-executable memory.
67     // https://bugs.webkit.org/show_bug.cgi?id=116189
68     UNUSED_PARAM(isReadOnly);
69     return mmAllocateCodeSection(opaqueState, size, alignment, sectionID);
70 }
71
72 static LLVMBool mmApplyPermissions(void*, char**)
73 {
74     return false;
75 }
76
77 static void mmDestroy(void*)
78 {
79 }
80
81 void compile(State& state)
82 {
83     char* error = 0;
84     
85     LLVMMCJITCompilerOptions options;
86     LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
87     options.OptLevel = Options::llvmOptimizationLevel();
88     options.NoFramePointerElim = true;
89     if (Options::useLLVMSmallCodeModel())
90         options.CodeModel = LLVMCodeModelSmall;
91     options.EnableFastISel = Options::enableLLVMFastISel();
92     options.MCJMM = LLVMCreateSimpleMCJITMemoryManager(
93         &state, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy);
94     
95     LLVMExecutionEngineRef engine;
96     
97     if (LLVMCreateMCJITCompilerForModule(&engine, state.module, &options, sizeof(options), &error)) {
98         dataLog("FATAL: Could not create LLVM execution engine: ", error, "\n");
99         CRASH();
100     }
101     
102     LLVMPassManagerRef pass = LLVMCreatePassManager();
103     LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
104     LLVMAddConstantPropagationPass(pass);
105     LLVMAddInstructionCombiningPass(pass);
106     LLVMAddPromoteMemoryToRegisterPass(pass);
107     if (Options::enableLLVMLICM())
108         LLVMAddLICMPass(pass);
109     LLVMAddGVNPass(pass);
110     LLVMAddCFGSimplificationPass(pass);
111     LLVMRunPassManager(pass, state.module);
112     if (DFG::shouldShowDisassembly() || DFG::verboseCompilationEnabled())
113         state.dumpState("after optimization");
114     
115     // FIXME: Need to add support for the case where JIT memory allocation failed.
116     // https://bugs.webkit.org/show_bug.cgi?id=113620
117     state.generatedFunction = reinterpret_cast<GeneratedFunction>(LLVMGetPointerToGlobal(engine, state.function));
118     LLVMDisposePassManager(pass);
119     LLVMDisposeExecutionEngine(engine);
120 }
121
122 } } // namespace JSC::FTL
123
124 #endif // ENABLE(FTL_JIT)
125