1/* 2 * Copyright (C) 2011, 2012, 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 "DFGDriver.h" 28 29#include "JSObject.h" 30#include "JSString.h" 31 32#include "CodeBlock.h" 33#include "DFGJITCode.h" 34#include "DFGPlan.h" 35#include "DFGThunks.h" 36#include "DFGWorklist.h" 37#include "JITCode.h" 38#include "JSCInlines.h" 39#include "Options.h" 40#include "SamplingTool.h" 41#include <wtf/Atomics.h> 42 43#if ENABLE(FTL_JIT) 44#include "FTLThunks.h" 45#endif 46 47namespace JSC { namespace DFG { 48 49static unsigned numCompilations; 50 51unsigned getNumCompilations() 52{ 53 return numCompilations; 54} 55 56#if ENABLE(DFG_JIT) 57static CompilationResult compileImpl( 58 VM& vm, CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationMode mode, 59 unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues, 60 PassRefPtr<DeferredCompilationCallback> callback) 61{ 62 SamplingRegion samplingRegion("DFG Compilation (Driver)"); 63 64 numCompilations++; 65 66 ASSERT(codeBlock); 67 ASSERT(codeBlock->alternative()); 68 ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT); 69 ASSERT(!profiledDFGCodeBlock || profiledDFGCodeBlock->jitType() == JITCode::DFGJIT); 70 71 if (logCompilationChanges(mode)) 72 dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n"); 73 74 // Make sure that any stubs that the DFG is going to use are initialized. We want to 75 // make sure that all JIT code generation does finalization on the main thread. 76 vm.getCTIStub(osrExitGenerationThunkGenerator); 77 vm.getCTIStub(throwExceptionFromCallSlowPathGenerator); 78 if (mode == DFGMode) { 79 vm.getCTIStub(linkCallThunkGenerator); 80 vm.getCTIStub(linkConstructThunkGenerator); 81 vm.getCTIStub(linkClosureCallThunkGenerator); 82 vm.getCTIStub(virtualCallThunkGenerator); 83 vm.getCTIStub(virtualConstructThunkGenerator); 84 } else { 85 vm.getCTIStub(linkCallThatPreservesRegsThunkGenerator); 86 vm.getCTIStub(linkConstructThatPreservesRegsThunkGenerator); 87 vm.getCTIStub(linkClosureCallThatPreservesRegsThunkGenerator); 88 vm.getCTIStub(virtualCallThatPreservesRegsThunkGenerator); 89 vm.getCTIStub(virtualConstructThatPreservesRegsThunkGenerator); 90 } 91 92 RefPtr<Plan> plan = adoptRef( 93 new Plan(codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues)); 94 95 if (Options::enableConcurrentJIT()) { 96 Worklist* worklist = ensureGlobalWorklistFor(mode); 97 plan->callback = callback; 98 if (logCompilationChanges(mode)) 99 dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", worklist->queueLength(), ".\n"); 100 worklist->enqueue(plan); 101 return CompilationDeferred; 102 } 103 104 plan->compileInThread(*vm.dfgState, 0); 105 return plan->finalizeWithoutNotifyingCallback(); 106} 107#else // ENABLE(DFG_JIT) 108static CompilationResult compileImpl( 109 VM&, CodeBlock*, CodeBlock*, CompilationMode, unsigned, const Operands<JSValue>&, 110 PassRefPtr<DeferredCompilationCallback>) 111{ 112 return CompilationFailed; 113} 114#endif // ENABLE(DFG_JIT) 115 116CompilationResult compile( 117 VM& vm, CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationMode mode, 118 unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues, 119 PassRefPtr<DeferredCompilationCallback> passedCallback) 120{ 121 RefPtr<DeferredCompilationCallback> callback = passedCallback; 122 CompilationResult result = compileImpl( 123 vm, codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues, 124 callback); 125 if (result != CompilationDeferred) 126 callback->compilationDidComplete(codeBlock, result); 127 return result; 128} 129 130} } // namespace JSC::DFG 131