DFGDriver.cpp 7.1 KB

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