2  * Copyright (C) 2011, 2012, 2013 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 "DFGDriver.h" 
  35 #include "DFGArgumentsSimplificationPhase.h" 
  36 #include "DFGBackwardsPropagationPhase.h" 
  37 #include "DFGByteCodeParser.h" 
  38 #include "DFGCFAPhase.h" 
  39 #include "DFGCFGSimplificationPhase.h" 
  40 #include "DFGCPSRethreadingPhase.h" 
  41 #include "DFGCSEPhase.h" 
  42 #include "DFGConstantFoldingPhase.h" 
  43 #include "DFGDCEPhase.h" 
  44 #include "DFGFixupPhase.h" 
  45 #include "DFGJITCompiler.h" 
  46 #include "DFGPredictionInjectionPhase.h" 
  47 #include "DFGPredictionPropagationPhase.h" 
  48 #include "DFGTypeCheckHoistingPhase.h" 
  49 #include "DFGUnificationPhase.h" 
  50 #include "DFGValidate.h" 
  51 #include "DFGVirtualRegisterAllocationPhase.h" 
  52 #include "Operations.h" 
  55 namespace JSC 
{ namespace DFG 
{ 
  57 static unsigned numCompilations
; 
  59 unsigned getNumCompilations() 
  61     return numCompilations
; 
  64 enum CompileMode 
{ CompileFunction
, CompileOther 
}; 
  65 inline bool compile(CompileMode compileMode
, ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, MacroAssemblerCodePtr
* jitCodeWithArityCheck
, unsigned osrEntryBytecodeIndex
) 
  67     SamplingRegion 
samplingRegion("DFG Compilation (Driver)"); 
  72     ASSERT(codeBlock
->alternative()); 
  73     ASSERT(codeBlock
->alternative()->getJITType() == JITCode::BaselineJIT
); 
  75     ASSERT(osrEntryBytecodeIndex 
!= UINT_MAX
); 
  77     if (!Options::useDFGJIT()) 
  80     if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock
->instructionCount())) 
  83     if (logCompilationChanges()) 
  84         dataLog("DFG compiling ", *codeBlock
, ", number of instructions = ", codeBlock
->instructionCount(), "\n"); 
  86     // Derive our set of must-handle values. The compilation must be at least conservative 
  87     // enough to allow for OSR entry with these values. 
  88     unsigned numVarsWithValues
; 
  89     if (osrEntryBytecodeIndex
) 
  90         numVarsWithValues 
= codeBlock
->m_numVars
; 
  92         numVarsWithValues 
= 0; 
  93     Operands
<JSValue
> mustHandleValues(codeBlock
->numParameters(), numVarsWithValues
); 
  94     for (size_t i 
= 0; i 
< mustHandleValues
.size(); ++i
) { 
  95         int operand 
= mustHandleValues
.operandForIndex(i
); 
  96         if (operandIsArgument(operand
) 
  97             && !operandToArgument(operand
) 
  98             && compileMode 
== CompileFunction
 
  99             && codeBlock
->specializationKind() == CodeForConstruct
) { 
 100             // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will 
 101             // also never be used. It doesn't matter what we put into the value for this, 
 102             // but it has to be an actual value that can be grokked by subsequent DFG passes, 
 103             // so we sanitize it here by turning it into Undefined. 
 104             mustHandleValues
[i
] = jsUndefined(); 
 106             mustHandleValues
[i
] = exec
->uncheckedR(operand
).jsValue(); 
 109     Graph 
dfg(exec
->vm(), codeBlock
, osrEntryBytecodeIndex
, mustHandleValues
); 
 110     if (!parse(exec
, dfg
)) 
 113     // By this point the DFG bytecode parser will have potentially mutated various tables 
 114     // in the CodeBlock. This is a good time to perform an early shrink, which is more 
 115     // powerful than a late one. It's safe to do so because we haven't generated any code 
 116     // that references any of the tables directly, yet. 
 117     codeBlock
->shrinkToFit(CodeBlock::EarlyShrink
); 
 119     if (validationEnabled()) 
 122     performCPSRethreading(dfg
); 
 123     performUnification(dfg
); 
 124     performPredictionInjection(dfg
); 
 126     if (validationEnabled()) 
 129     performBackwardsPropagation(dfg
); 
 130     performPredictionPropagation(dfg
); 
 132     performTypeCheckHoisting(dfg
); 
 134     dfg
.m_fixpointState 
= FixpointNotConverged
; 
 137     performArgumentsSimplification(dfg
); 
 138     performCPSRethreading(dfg
); // This should usually be a no-op since CSE rarely dethreads, and arguments simplification rarely does anything. 
 140     performConstantFolding(dfg
); 
 141     performCFGSimplification(dfg
); 
 143     dfg
.m_fixpointState 
= FixpointConverged
; 
 145     performStoreElimination(dfg
); 
 146     performCPSRethreading(dfg
); 
 148     performVirtualRegisterAllocation(dfg
); 
 150     GraphDumpMode modeForFinalValidate 
= DumpGraph
; 
 151     if (verboseCompilationEnabled()) { 
 152         dataLogF("Graph after optimization:\n"); 
 154         modeForFinalValidate 
= DontDumpGraph
; 
 156     if (validationEnabled()) 
 157         validate(dfg
, modeForFinalValidate
); 
 159     JITCompiler 
dataFlowJIT(dfg
); 
 161     if (compileMode 
== CompileFunction
) { 
 162         ASSERT(jitCodeWithArityCheck
); 
 164         result 
= dataFlowJIT
.compileFunction(jitCode
, *jitCodeWithArityCheck
); 
 166         ASSERT(compileMode 
== CompileOther
); 
 167         ASSERT(!jitCodeWithArityCheck
); 
 169         result 
= dataFlowJIT
.compile(jitCode
); 
 175 bool tryCompile(ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, unsigned bytecodeIndex
) 
 177     return compile(CompileOther
, exec
, codeBlock
, jitCode
, 0, bytecodeIndex
); 
 180 bool tryCompileFunction(ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, MacroAssemblerCodePtr
& jitCodeWithArityCheck
, unsigned bytecodeIndex
) 
 182     return compile(CompileFunction
, exec
, codeBlock
, jitCode
, &jitCodeWithArityCheck
, bytecodeIndex
); 
 185 } } // namespace JSC::DFG 
 187 #endif // ENABLE(DFG_JIT)