DFGCapabilities.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (C) 2011 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 "DFGCapabilities.h"
  27. #include "CodeBlock.h"
  28. #include "DFGCommon.h"
  29. #include "Interpreter.h"
  30. namespace JSC { namespace DFG {
  31. #if ENABLE(DFG_JIT)
  32. bool mightCompileEval(CodeBlock* codeBlock)
  33. {
  34. return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
  35. }
  36. bool mightCompileProgram(CodeBlock* codeBlock)
  37. {
  38. return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
  39. }
  40. bool mightCompileFunctionForCall(CodeBlock* codeBlock)
  41. {
  42. return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
  43. }
  44. bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
  45. {
  46. return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
  47. }
  48. bool mightInlineFunctionForCall(CodeBlock* codeBlock)
  49. {
  50. return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
  51. && !codeBlock->ownerExecutable()->needsActivation();
  52. }
  53. bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
  54. {
  55. return codeBlock->instructionCount() <= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount()
  56. && !codeBlock->ownerExecutable()->needsActivation();
  57. }
  58. bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
  59. {
  60. return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
  61. && !codeBlock->ownerExecutable()->needsActivation();
  62. }
  63. static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, bool result)
  64. {
  65. ASSERT_UNUSED(result, !result);
  66. #if DFG_ENABLE(DEBUG_VERBOSE)
  67. dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]);
  68. #else
  69. UNUSED_PARAM(codeBlock);
  70. UNUSED_PARAM(opcodeID);
  71. UNUSED_PARAM(result);
  72. #endif
  73. }
  74. static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
  75. {
  76. ASSERT(result != CanCompile);
  77. #if DFG_ENABLE(DEBUG_VERBOSE)
  78. if (result == CannotCompile)
  79. dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]);
  80. else {
  81. dataLogF("Cannot compile code block %p because of opcode %s, but inlining might be possible.\n", codeBlock, opcodeNames[opcodeID]);
  82. }
  83. #else
  84. UNUSED_PARAM(codeBlock);
  85. UNUSED_PARAM(opcodeID);
  86. UNUSED_PARAM(result);
  87. #endif
  88. }
  89. template<typename ReturnType, ReturnType (*canHandleOpcode)(OpcodeID, CodeBlock*, Instruction*)>
  90. ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue)
  91. {
  92. Interpreter* interpreter = codeBlock->vm()->interpreter;
  93. Instruction* instructionsBegin = codeBlock->instructions().begin();
  94. unsigned instructionCount = codeBlock->instructions().size();
  95. ReturnType result = initialValue;
  96. for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) {
  97. switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) {
  98. #define DEFINE_OP(opcode, length) \
  99. case opcode: { \
  100. ReturnType current = canHandleOpcode( \
  101. opcode, codeBlock, instructionsBegin + bytecodeOffset); \
  102. if (current < result) { \
  103. result = current; \
  104. debugFail(codeBlock, opcode, current); \
  105. } \
  106. bytecodeOffset += length; \
  107. break; \
  108. }
  109. FOR_EACH_OPCODE_ID(DEFINE_OP)
  110. #undef DEFINE_OP
  111. default:
  112. RELEASE_ASSERT_NOT_REACHED();
  113. break;
  114. }
  115. }
  116. return result;
  117. }
  118. CapabilityLevel canCompileOpcodes(CodeBlock* codeBlock)
  119. {
  120. if (!MacroAssembler::supportsFloatingPoint())
  121. return CannotCompile;
  122. return canHandleOpcodes<CapabilityLevel, canCompileOpcode>(codeBlock, CanCompile);
  123. }
  124. bool canInlineOpcodes(CodeBlock* codeBlock)
  125. {
  126. return canHandleOpcodes<bool, canInlineOpcode>(codeBlock, true);
  127. }
  128. #endif
  129. } } // namespace JSC::DFG