1/* 2 * Copyright (C) 2013, 2014 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 "FTLJITFinalizer.h" 28 29#if ENABLE(FTL_JIT) 30 31#include "CodeBlockWithJITType.h" 32#include "DFGPlan.h" 33#include "FTLThunks.h" 34#include "ProfilerDatabase.h" 35 36namespace JSC { namespace FTL { 37 38using namespace DFG; 39 40JITFinalizer::JITFinalizer(Plan& plan) 41 : Finalizer(plan) 42{ 43} 44 45JITFinalizer::~JITFinalizer() 46{ 47} 48 49size_t JITFinalizer::codeSize() 50{ 51 size_t result = 0; 52 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(); 61 62 for (unsigned i = jitCode->handles().size(); i--;) 63 result += jitCode->handles()[i]->sizeInBytes(); 64 65 return result; 66} 67 68bool JITFinalizer::finalize() 69{ 70 RELEASE_ASSERT_NOT_REACHED(); 71 return false; 72} 73 74bool JITFinalizer::finalizeFunction() 75{ 76 for (unsigned i = jitCode->handles().size(); i--;) { 77 MacroAssembler::cacheFlush( 78 jitCode->handles()[i]->start(), jitCode->handles()[i]->sizeInBytes()); 79 } 80 81 if (exitThunksLinkBuffer) { 82 StackMaps::RecordMap recordMap = jitCode->stackmaps.computeRecordMap(); 83 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. 90 continue; 91 } 92 93 exitThunksLinkBuffer->link( 94 info.m_thunkJump, 95 CodeLocationLabel( 96 m_plan.vm.getCTIStub(osrExitGenerationThunkGenerator).code())); 97 } 98 99 jitCode->initializeExitThunks( 100 FINALIZE_DFG_CODE( 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. 104 105 if (sideCodeLinkBuffer) { 106 // Side code is for special slow paths that we generate ourselves, like for inline 107 // caches. 108 109 for (unsigned i = slowPathCalls.size(); i--;) { 110 SlowPathCall& call = slowPathCalls[i]; 111 sideCodeLinkBuffer->link( 112 call.call(), 113 CodeLocationLabel(m_plan.vm.ftlThunks->getSlowPathCallThunk(m_plan.vm, call.key()).code())); 114 } 115 116 jitCode->addHandle(FINALIZE_DFG_CODE( 117 *sideCodeLinkBuffer, 118 ("FTL side code for %s", 119 toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data())) 120 .executableMemory()); 121 } 122 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()); 129 } 130 131 jitCode->initializeArityCheckEntrypoint( 132 FINALIZE_DFG_CODE( 133 *entrypointLinkBuffer, 134 ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), function))); 135 136 m_plan.codeBlock->setJITCode(jitCode); 137 138 m_plan.vm.updateFTLLargestStackSize(jitCode->stackmaps.stackSize()); 139 140 if (m_plan.compilation) 141 m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.compilation); 142 143 return true; 144} 145 146} } // namespace JSC::FTL 147 148#endif // ENABLE(FTL_JIT) 149 150