2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "FTLJITFinalizer.h"
31 #include "CodeBlockWithJITType.h"
33 #include "FTLThunks.h"
34 #include "ProfilerDatabase.h"
36 namespace JSC
{ namespace FTL
{
40 JITFinalizer::JITFinalizer(Plan
& plan
)
45 JITFinalizer::~JITFinalizer()
49 size_t JITFinalizer::codeSize()
53 if (exitThunksLinkBuffer
)
54 result
+= exitThunksLinkBuffer
->size();
55 if (entrypointLinkBuffer
)
56 result
+= entrypointLinkBuffer
->size();
57 if (sideCodeLinkBuffer
)
58 result
+= sideCodeLinkBuffer
->size();
59 if (handleExceptionsLinkBuffer
)
60 result
+= handleExceptionsLinkBuffer
->size();
62 for (unsigned i
= jitCode
->handles().size(); i
--;)
63 result
+= jitCode
->handles()[i
]->sizeInBytes();
68 bool JITFinalizer::finalize()
70 RELEASE_ASSERT_NOT_REACHED();
74 bool JITFinalizer::finalizeFunction()
76 for (unsigned i
= jitCode
->handles().size(); i
--;) {
77 MacroAssembler::cacheFlush(
78 jitCode
->handles()[i
]->start(), jitCode
->handles()[i
]->sizeInBytes());
81 if (exitThunksLinkBuffer
) {
82 StackMaps::RecordMap recordMap
= jitCode
->stackmaps
.computeRecordMap();
84 for (unsigned i
= 0; i
< osrExit
.size(); ++i
) {
85 OSRExitCompilationInfo
& info
= osrExit
[i
];
86 OSRExit
& exit
= jitCode
->osrExit
[i
];
87 StackMaps::RecordMap::iterator iter
= recordMap
.find(exit
.m_stackmapID
);
88 if (iter
== recordMap
.end()) {
89 // It's OK, it was optimized out.
93 exitThunksLinkBuffer
->link(
96 m_plan
.vm
.getCTIStub(osrExitGenerationThunkGenerator
).code()));
99 jitCode
->initializeExitThunks(
101 *exitThunksLinkBuffer
,
102 ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan
.codeBlock
.get(), JITCode::FTLJIT
)).data())));
103 } // else this function had no OSR exits, so no exit thunks.
105 if (sideCodeLinkBuffer
) {
106 // Side code is for special slow paths that we generate ourselves, like for inline
109 for (unsigned i
= slowPathCalls
.size(); i
--;) {
110 SlowPathCall
& call
= slowPathCalls
[i
];
111 sideCodeLinkBuffer
->link(
113 CodeLocationLabel(m_plan
.vm
.ftlThunks
->getSlowPathCallThunk(m_plan
.vm
, call
.key()).code()));
116 jitCode
->addHandle(FINALIZE_DFG_CODE(
118 ("FTL side code for %s",
119 toCString(CodeBlockWithJITType(m_plan
.codeBlock
.get(), JITCode::FTLJIT
)).data()))
120 .executableMemory());
123 if (handleExceptionsLinkBuffer
) {
124 jitCode
->addHandle(FINALIZE_DFG_CODE(
125 *handleExceptionsLinkBuffer
,
126 ("FTL exception handler for %s",
127 toCString(CodeBlockWithJITType(m_plan
.codeBlock
.get(), JITCode::FTLJIT
)).data()))
128 .executableMemory());
131 jitCode
->initializeArityCheckEntrypoint(
133 *entrypointLinkBuffer
,
134 ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan
.codeBlock
.get(), JITCode::FTLJIT
)).data(), function
)));
136 m_plan
.codeBlock
->setJITCode(jitCode
);
138 m_plan
.vm
.updateFTLLargestStackSize(jitCode
->stackmaps
.stackSize());
140 if (m_plan
.compilation
)
141 m_plan
.vm
.m_perBytecodeProfiler
->addCompilation(m_plan
.compilation
);
146 } } // namespace JSC::FTL
148 #endif // ENABLE(FTL_JIT)