1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_DFX_STACKINFO_JS_STACKGETTER_H 17 #define ECMASCRIPT_DFX_STACKINFO_JS_STACKGETTER_H 18 19 #include <csignal> 20 21 #include "ecmascript/compiler/share_gate_meta_data.h" 22 #include "ecmascript/deoptimizer/deoptimizer.h" 23 #include "ecmascript/interpreter/frame_handler.h" 24 25 namespace panda::ecmascript { 26 enum class RunningState : size_t { 27 OTHER = 0, 28 GC, 29 CINT, 30 AINT, 31 AOT, 32 BUILTIN, 33 NAPI, 34 ARKUI_ENGINE, 35 RUNTIME 36 }; 37 38 struct MethodKey { 39 void *methodIdentifier = nullptr; 40 RunningState state = RunningState::OTHER; 41 kungfu::DeoptType deoptType = kungfu::DeoptType::NOTCHECK; 42 int lineNumber = 0; 43 bool operator < (const MethodKey &methodKey) const 44 { 45 return state < methodKey.state || 46 (state == methodKey.state && methodIdentifier < methodKey.methodIdentifier) || 47 (state == methodKey.state && methodIdentifier == methodKey.methodIdentifier && 48 deoptType < methodKey.deoptType) || 49 (state == methodKey.state && methodIdentifier == methodKey.methodIdentifier && 50 deoptType == methodKey.deoptType && lineNumber < methodKey.lineNumber); 51 } 52 }; 53 54 struct NodeKey { 55 struct MethodKey methodKey = {0}; 56 int parentId = 0; 57 bool operator < (const NodeKey &nodeKey) const 58 { 59 return parentId < nodeKey.parentId || 60 (parentId == nodeKey.parentId && methodKey < nodeKey.methodKey); 61 } 62 }; 63 64 struct FrameInfoTemp { 65 char codeType[20] = {0}; // 20:the maximum size of the codeType 66 char functionName[100] = {0}; // 100:the maximum size of the functionName 67 char recordName[500] = {0}; // 500:the maximum size of the recordName 68 int columnNumber = -1; 69 int lineNumber = -1; 70 int scriptId = 0; 71 char url[500] = {0}; // 500:the maximum size of the url 72 struct MethodKey methodKey = {0}; 73 }; 74 75 class JsStackGetter { 76 public: 77 static bool CheckFrameType(JSThread *thread, JSTaggedType *sp); 78 static bool ParseMethodInfo(struct MethodKey &methodKey, 79 const FrameIterator &it, 80 const EcmaVM *vm, 81 FrameInfoTemp &codeEntry, 82 bool isCpuProfiler = false); 83 static bool CheckAndCopy(char *dest, size_t length, const char *src); 84 static void GetNativeStack(const EcmaVM *vm, const FrameIterator &it, char *functionName, 85 size_t size, bool isCpuProfiler); 86 static RunningState GetRunningState(const FrameIterator &it, const EcmaVM *vm, bool isNative, 87 bool topFrame, bool enableVMTag = false); 88 static void GetNativeMethodCallPos(FrameIterator &it, FrameInfoTemp &codeEntry); 89 static void *GetMethodIdentifier(Method *method, const FrameIterator &it); 90 static void GetCallLineNumber(const FrameIterator &it, int &LineNumber); 91 }; 92 } // namespace panda::ecmascript 93 #endif // ECMASCRIPT_DFX_STACKINFO_JS_STACKGETTER_H