forked from chakra-core/ChakraCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemoryLogger.cpp
More file actions
104 lines (91 loc) · 3.68 KB
/
MemoryLogger.cpp
File metadata and controls
104 lines (91 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "CommonMemoryPch.h"
#include "MemoryLogger.h"
#ifdef ENABLE_TRACE
namespace Js
{
MemoryLogger::MemoryLogger(TAllocator* alloc, ULONG count) : m_alloc(alloc), m_capacity(count), m_current(0)
{
m_log = AnewArrayZ(m_alloc, wchar_t*, m_capacity);
}
MemoryLogger::~MemoryLogger()
{
Adelete(m_alloc, m_log);
}
void MemoryLogger::Write(const wchar_t* msg)
{
#ifdef EXCEPTION_CHECK
// In most cases this will be called at runtime when we have exception check enabled.
AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
AutoCriticalSection autocs(&m_criticalSection); // TODO: with circular buffer now we can use much granular lock.
// Create a copy of the message.
size_t len = wcslen(msg);
wchar_t* buf = AnewArray(m_alloc, wchar_t, len + 1);
js_wmemcpy_s(buf, len + 1, msg, len + 1); // Copy with the NULL-terminator.
// m_current is the next position to write to.
if (m_log[m_current])
{
Adelete(m_alloc, m_log[m_current]);
}
m_log[m_current] = buf;
m_current = (m_current + 1) % m_capacity;
}
MemoryLogger* MemoryLogger::Create(TAllocator* alloc, ULONG count)
{
#ifdef EXCEPTION_CHECK
AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
return Anew(alloc, MemoryLogger, alloc, count);
}
#ifdef STACK_BACK_TRACE
StackTraceHelper* StackTraceHelper::Create(TAllocator* alloc)
{
#ifdef EXCEPTION_CHECK
AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
return Anew(alloc, StackTraceHelper, alloc);
}
// Capture and fill buffer.
ULONG StackTraceHelper::GetStackTrace(ULONG framesToSkip, ULONG framesToCapture, void** stackFrames)
{
#ifdef EXCEPTION_CHECK
AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
StackBackTrace* stackTrace = this->GetStackBackTrace(framesToCapture);
ULONG capturedCount = stackTrace->Capture(framesToSkip);
Assert(capturedCount <= framesToCapture);
ULONG i = 0;
stackTrace->Map([&i, framesToCapture, stackFrames](void* funcAddr){
Assert(i <= framesToCapture);
stackFrames[i++] = funcAddr;
});
return capturedCount;
}
// Capture and print.
size_t StackTraceHelper::PrintStackTrace(ULONG framesToSkip, ULONG framesToCapture)
{
#ifdef EXCEPTION_CHECK
AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
StackBackTrace* stackTrace = this->GetStackBackTrace(framesToCapture);
stackTrace->Capture(framesToSkip);
return stackTrace->Print();
}
StackBackTrace* StackTraceHelper::GetStackBackTrace(ULONG frameCount)
{
// Create, if we haven't already for calling thread.
if (!s_stackBackTrace)
{
s_stackBackTrace = StackBackTrace::Create(m_alloc, frameCount);
}
Assert(s_stackBackTrace->GetRequestedFrameCount() >= frameCount);
return s_stackBackTrace;
}
__declspec(thread) StackBackTrace* StackTraceHelper::s_stackBackTrace = nullptr;
#endif STACK_BACK_TRACE
}
#endif ENABLE_TRACE