CodeOrigin.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. #ifndef CodeOrigin_h
  26. #define CodeOrigin_h
  27. #include "CodeBlockHash.h"
  28. #include "CodeSpecializationKind.h"
  29. #include "ValueRecovery.h"
  30. #include "WriteBarrier.h"
  31. #include <wtf/BitVector.h>
  32. #include <wtf/PrintStream.h>
  33. #include <wtf/StdLibExtras.h>
  34. #include <wtf/Vector.h>
  35. namespace JSC {
  36. struct InlineCallFrame;
  37. class ExecState;
  38. class ExecutableBase;
  39. class JSFunction;
  40. struct CodeOrigin {
  41. static const unsigned maximumBytecodeIndex = (1u << 29) - 1;
  42. // Bytecode offset that you'd use to re-execute this instruction.
  43. unsigned bytecodeIndex : 29;
  44. // Bytecode offset corresponding to the opcode that gives the result (needed to handle
  45. // op_call/op_call_put_result and op_method_check/op_get_by_id).
  46. unsigned valueProfileOffset : 3;
  47. InlineCallFrame* inlineCallFrame;
  48. CodeOrigin()
  49. : bytecodeIndex(maximumBytecodeIndex)
  50. , valueProfileOffset(0)
  51. , inlineCallFrame(0)
  52. {
  53. }
  54. explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0, unsigned valueProfileOffset = 0)
  55. : bytecodeIndex(bytecodeIndex)
  56. , valueProfileOffset(valueProfileOffset)
  57. , inlineCallFrame(inlineCallFrame)
  58. {
  59. RELEASE_ASSERT(bytecodeIndex <= maximumBytecodeIndex);
  60. RELEASE_ASSERT(valueProfileOffset < (1u << 3));
  61. }
  62. bool isSet() const { return bytecodeIndex != maximumBytecodeIndex; }
  63. unsigned bytecodeIndexForValueProfile() const
  64. {
  65. return bytecodeIndex + valueProfileOffset;
  66. }
  67. // The inline depth is the depth of the inline stack, so 1 = not inlined,
  68. // 2 = inlined one deep, etc.
  69. unsigned inlineDepth() const;
  70. // If the code origin corresponds to inlined code, gives you the heap object that
  71. // would have owned the code if it had not been inlined. Otherwise returns 0.
  72. ExecutableBase* codeOriginOwner() const;
  73. unsigned stackOffset() const;
  74. static unsigned inlineDepthForCallFrame(InlineCallFrame*);
  75. bool operator==(const CodeOrigin& other) const;
  76. bool operator!=(const CodeOrigin& other) const { return !(*this == other); }
  77. // Get the inline stack. This is slow, and is intended for debugging only.
  78. Vector<CodeOrigin> inlineStack() const;
  79. void dump(PrintStream&) const;
  80. };
  81. struct InlineCallFrame {
  82. Vector_shared<ValueRecovery> arguments;
  83. WriteBarrier<ExecutableBase> executable;
  84. WriteBarrier<JSFunction> callee; // This may be null, indicating that this is a closure call and that the JSFunction and JSScope are already on the stack.
  85. CodeOrigin caller;
  86. BitVector_shared capturedVars; // Indexed by the machine call frame's variable numbering.
  87. unsigned stackOffset : 31;
  88. bool isCall : 1;
  89. CodeSpecializationKind specializationKind() const { return specializationFromIsCall(isCall); }
  90. bool isClosureCall() const { return !callee; }
  91. // Get the callee given a machine call frame to which this InlineCallFrame belongs.
  92. JSFunction* calleeForCallFrame(ExecState*) const;
  93. String inferredName() const;
  94. CodeBlockHash hash() const;
  95. CodeBlock* baselineCodeBlock() const;
  96. void dumpBriefFunctionInformation(PrintStream&) const;
  97. void dump(PrintStream&) const;
  98. MAKE_PRINT_METHOD(InlineCallFrame, dumpBriefFunctionInformation, briefFunctionInformation);
  99. };
  100. struct CodeOriginAtCallReturnOffset {
  101. CodeOrigin codeOrigin;
  102. unsigned callReturnOffset;
  103. };
  104. inline unsigned CodeOrigin::stackOffset() const
  105. {
  106. if (!inlineCallFrame)
  107. return 0;
  108. return inlineCallFrame->stackOffset;
  109. }
  110. inline bool CodeOrigin::operator==(const CodeOrigin& other) const
  111. {
  112. return bytecodeIndex == other.bytecodeIndex
  113. && inlineCallFrame == other.inlineCallFrame;
  114. }
  115. inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* data)
  116. {
  117. return data->callReturnOffset;
  118. }
  119. inline ExecutableBase* CodeOrigin::codeOriginOwner() const
  120. {
  121. if (!inlineCallFrame)
  122. return 0;
  123. return inlineCallFrame->executable.get();
  124. }
  125. } // namespace JSC
  126. #endif // CodeOrigin_h