Replace WTF::move with WTFMove
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLB3Compile.cpp
1 /*
2  * Copyright (C) 2015 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) && FTL_USES_B3
30
31 #include "B3Generate.h"
32 #include "B3ProcedureInlines.h"
33 #include "B3StackSlotValue.h"
34 #include "CodeBlockWithJITType.h"
35 #include "CCallHelpers.h"
36 #include "DFGCommon.h"
37 #include "DFGGraphSafepoint.h"
38 #include "DFGOperations.h"
39 #include "DataView.h"
40 #include "Disassembler.h"
41 #include "FTLExceptionHandlerManager.h"
42 #include "FTLExitThunkGenerator.h"
43 #include "FTLInlineCacheSize.h"
44 #include "FTLJITCode.h"
45 #include "FTLThunks.h"
46 #include "FTLUnwindInfo.h"
47 #include "JITSubGenerator.h"
48 #include "LinkBuffer.h"
49 #include "ScratchRegisterAllocator.h"
50
51 namespace JSC { namespace FTL {
52
53 using namespace DFG;
54
55 void compile(State& state, Safepoint::Result& safepointResult)
56 {
57     Graph& graph = state.graph;
58     CodeBlock* codeBlock = graph.m_codeBlock;
59     VM& vm = graph.m_vm;
60     
61     {
62         GraphSafepoint safepoint(state.graph, safepointResult);
63
64         B3::prepareForGeneration(*state.proc);
65     }
66
67     if (safepointResult.didGetCancelled())
68         return;
69     RELEASE_ASSERT(!state.graph.m_vm.heap.isCollecting());
70     
71     if (state.allocationFailed)
72         return;
73     
74     std::unique_ptr<RegisterAtOffsetList> registerOffsets =
75         std::make_unique<RegisterAtOffsetList>(state.proc->calleeSaveRegisters());
76     if (shouldDumpDisassembly()) {
77         dataLog("Unwind info for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ":\n");
78         dataLog("    ", *registerOffsets, "\n");
79     }
80     state.graph.m_codeBlock->setCalleeSaveRegisters(WTFMove(registerOffsets));
81     ASSERT(!(state.proc->frameSize() % sizeof(EncodedJSValue)));
82     state.jitCode->common.frameRegisterCount = state.proc->frameSize() / sizeof(EncodedJSValue);
83
84     int localsOffset =
85         state.capturedValue->offsetFromFP() / sizeof(EncodedJSValue) + graph.m_nextMachineLocal;
86     for (unsigned i = graph.m_inlineVariableData.size(); i--;) {
87         InlineCallFrame* inlineCallFrame = graph.m_inlineVariableData[i].inlineCallFrame;
88         
89         if (inlineCallFrame->argumentCountRegister.isValid())
90             inlineCallFrame->argumentCountRegister += localsOffset;
91         
92         for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
93             inlineCallFrame->arguments[argument] =
94                 inlineCallFrame->arguments[argument].withLocalsOffset(localsOffset);
95         }
96         
97         if (inlineCallFrame->isClosureCall) {
98             inlineCallFrame->calleeRecovery =
99                 inlineCallFrame->calleeRecovery.withLocalsOffset(localsOffset);
100         }
101
102         if (graph.hasDebuggerEnabled())
103             codeBlock->setScopeRegister(codeBlock->scopeRegister() + localsOffset);
104     }
105     for (OSRExitDescriptor& descriptor : state.jitCode->osrExitDescriptors) {
106         for (unsigned i = descriptor.m_values.size(); i--;)
107             descriptor.m_values[i] = descriptor.m_values[i].withLocalsOffset(localsOffset);
108         for (ExitTimeObjectMaterialization* materialization : descriptor.m_materializations)
109             materialization->accountForLocalsOffset(localsOffset);
110     }
111
112     CCallHelpers jit(&vm, codeBlock);
113     B3::generate(*state.proc, jit);
114
115     state.finalizer->b3CodeLinkBuffer = std::make_unique<LinkBuffer>(
116         vm, jit, codeBlock, JITCompilationCanFail);
117     if (state.finalizer->b3CodeLinkBuffer->didFailToAllocate()) {
118         state.allocationFailed = true;
119         return;
120     }
121
122     state.generatedFunction = bitwise_cast<GeneratedFunction>(
123         state.finalizer->b3CodeLinkBuffer->entrypoint().executableAddress());
124     state.jitCode->initializeB3Byproducts(state.proc->releaseByproducts());
125 }
126
127 } } // namespace JSC::FTL
128
129 #endif // ENABLE(FTL_JIT) && FTL_USES_B3
130