ProbeContainer.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. #ifdef ENABLE_MUTATION_BREAKPOINT
  9. class MutationBreakpoint;
  10. #endif
  11. class DebugManager;
  12. struct Probe;
  13. typedef JsUtil::List<Probe*, ArenaAllocator> ProbeList;
  14. class DiagStackFrame;
  15. typedef JsUtil::Stack<DiagStackFrame*> DiagStack;
  16. typedef WeakArenaReference<DiagStack> WeakDiagStack;
  17. struct InterpreterHaltState;
  18. // This class contains the probes and list of function bodies.
  19. // The object of this class is maintained by ScriptContext.
  20. class ProbeContainer
  21. {
  22. friend class RecyclableObjectDisplay;
  23. friend class RecyclableArrayWalker;
  24. private:
  25. ProbeList* diagProbeList;
  26. ProbeList* pendingProbeList;
  27. ScriptContext* pScriptContext;
  28. DebugManager *debugManager;
  29. // Stack for a current scriptcontext
  30. DiagStack* framePointers;
  31. HaltCallback* haltCallbackProbe;
  32. DebuggerOptionsCallback* debuggerOptionsCallback;
  33. // Refer to the callback which is responsible for making async break
  34. HaltCallback* pAsyncHaltCallback;
  35. Var jsExceptionObject;
  36. // Used for synchronizing with ProbeMananger
  37. ulong debugSessionNumber;
  38. uint32 tmpRegCount; // Mentions the temp register count for the current statement (this will be used to determine if SetNextStatement can be applied)
  39. // Used when SetNextStatement is applied.
  40. int bytecodeOffset;
  41. bool IsNextStatementChanged;
  42. // Used when the throw is internal and engine does not want to be broken at exception.
  43. bool isThrowInternal;
  44. // This variabled will be set true when we don't want to check for debug script engine being initialized.
  45. bool forceBypassDebugEngine;
  46. bool isPrimaryBrokenToDebuggerContext;
  47. JsUtil::List<DWORD_PTR, ArenaAllocator> *registeredFuncContextList;
  48. JsUtil::List<const Js::PropertyRecord*> *pinnedPropertyRecords;
  49. void UpdateFramePointers(bool fMatchWithCurrentScriptContext);
  50. bool InitializeLocation(InterpreterHaltState* pHaltState, bool fMatchWithCurrentScriptContext = true);
  51. void DestroyLocation();
  52. bool ProbeContainer::GetNextUserStatementOffsetHelper(
  53. Js::FunctionBody* functionBody, int currentOffset, FunctionBody::StatementAdjustmentType adjType, int* nextStatementOffset);
  54. #ifdef ENABLE_MUTATION_BREAKPOINT
  55. void InitMutationBreakpointListIfNeeded();
  56. void ClearMutationBreakpoints();
  57. void RemoveMutationBreakpointListIfNeeded();
  58. #endif
  59. static bool FetchTmpRegCount(Js::FunctionBody * functionBody, Js::ByteCodeReader * reader, int atOffset, uint32 *pTmpRegCount, Js::OpCode *pOp);
  60. public:
  61. bool isForcedToEnterScriptStart;
  62. ProbeContainer();
  63. ~ProbeContainer();
  64. void StartRecordingCall();
  65. void EndRecordingCall(Js::Var returnValue, Js::JavascriptFunction * function);
  66. ReturnedValueList* GetReturnedValueList() const;
  67. void ResetReturnedValueList();
  68. void Initialize(ScriptContext* pScriptContext);
  69. void Close();
  70. WeakDiagStack* GetFramePointers();
  71. // A break engine responsible for breaking at iniline statement and error statement.
  72. void InitializeInlineBreakEngine(HaltCallback* pProbe);
  73. void InitializeDebuggerScriptOptionCallback(DebuggerOptionsCallback* debuggerOptionsCallback);
  74. void UninstallInlineBreakpointProbe(HaltCallback* pProbe);
  75. void UninstallDebuggerScriptOptionCallback();
  76. void AddProbe(Probe* pProbe);
  77. void RemoveProbe(Probe* pProbe);
  78. void RemoveAllProbes();
  79. bool CanDispatchHalt(InterpreterHaltState* pHaltState);
  80. // When on breakpoint hit
  81. void DispatchProbeHandlers(InterpreterHaltState* pHaltState);
  82. // When on step in, step out and step over
  83. void DispatchStepHandler(InterpreterHaltState* pHaltState, OpCode* pOriginalOpcode);
  84. // When on break-all
  85. void DispatchAsyncBreak(InterpreterHaltState* pHaltState);
  86. // When executing 'debugger' statement
  87. void DispatchInlineBreakpoint(InterpreterHaltState* pHaltState);
  88. // When encountered and exception
  89. bool DispatchExceptionBreakpoint(InterpreterHaltState* pHaltState);
  90. // When on mutation breakpoint hit
  91. void DispatchMutationBreakpoint(InterpreterHaltState* pHaltState);
  92. void UpdateStep(bool fDuringSetupDebugApp = false);
  93. void DeactivateStep();
  94. bool GetNextUserStatementOffsetForSetNext(Js::FunctionBody* functionBody, int currentOffset, int* nextStatementOffset);
  95. bool GetNextUserStatementOffsetForAdvance(Js::FunctionBody* functionBody, ByteCodeReader* reader, int currentOffset, int* nextStatementOffset);
  96. bool AdvanceToNextUserStatement(Js::FunctionBody* functionBody, ByteCodeReader* reader);
  97. void SetNextStatementAt(int bytecodeOffset);
  98. bool IsSetNextStatementCalled() const { return IsNextStatementChanged; }
  99. int GetByteCodeOffset() const { Assert(IsNextStatementChanged); return bytecodeOffset; }
  100. void AsyncActivate(HaltCallback* haltCallback);
  101. void AsyncDeactivate();
  102. void PrepDiagForEnterScript();
  103. void RegisterContextToDiag(DWORD_PTR context, ArenaAllocator *alloc);
  104. bool IsContextRegistered(DWORD_PTR context);
  105. FunctionBody * GetGlobalFunc(ScriptContext* scriptContext, DWORD_PTR secondaryHostSourceContext);
  106. Var GetExceptionObject() { return jsExceptionObject; }
  107. bool HasAllowedForException(__in JavascriptExceptionObject* exceptionObject);
  108. void SetThrowIsInternal(bool set) { isThrowInternal = set; }
  109. bool IsFirstChanceExceptionEnabled();
  110. bool IsNonUserCodeSupportEnabled();
  111. bool IsLibraryStackFrameSupportEnabled();
  112. void SetCurrentTmpRegCount(uint32 set) { tmpRegCount = set; }
  113. uint32 GetCurrentTmpRegCount() const { return tmpRegCount; }
  114. void PinPropertyRecord(const Js::PropertyRecord *propertyRecord);
  115. bool IsPrimaryBrokenToDebuggerContext() const { return isPrimaryBrokenToDebuggerContext; }
  116. void SetIsPrimaryBrokenToDebuggerContext(bool set) { isPrimaryBrokenToDebuggerContext = set; }
  117. DebugManager *GetDebugManager() const { return this->debugManager; }
  118. #ifdef ENABLE_MUTATION_BREAKPOINT
  119. typedef JsUtil::List<RecyclerWeakReference<Js::MutationBreakpoint>*, Recycler, false, Js::WeakRefFreeListedRemovePolicy> MutationBreakpointList;
  120. RecyclerRootPtr<MutationBreakpointList> mutationBreakpointList;
  121. bool HasMutationBreakpoints();
  122. void InsertMutationBreakpoint(MutationBreakpoint *mutationBreakpoint);
  123. #endif
  124. static bool IsTmpRegCountIncreased(Js::FunctionBody* functionBody, ByteCodeReader* reader, int currentOffset, int nextStmOffset, bool restoreOffset);
  125. };
  126. } // namespace Js.