Unreviewed, rolling out r136597.
[WebKit-https.git] / Source / WTF / wtf / MemoryInstrumentation.cpp
1 /*
2  * Copyright (C) 2012 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "MemoryInstrumentation.h"
33
34 #include <wtf/MemoryObjectInfo.h>
35
36 #if DEBUG_POINTER_INSTRUMENTATION
37 #include <stdio.h>
38 #include <wtf/Assertions.h>
39 #endif
40
41 namespace WTF {
42
43 MemoryInstrumentation::MemoryInstrumentation(MemoryInstrumentationClient* client)
44     : m_client(client)
45     , m_rootObjectInfo(adoptPtr(new MemoryObjectInfo(this, 0)))
46 {
47 }
48
49 MemoryInstrumentation::~MemoryInstrumentation()
50 {
51 }
52
53 void MemoryInstrumentation::reportEdge(MemoryObjectInfo* ownerObjectInfo, const void* target, const char* name)
54 {
55     m_client->reportEdge(ownerObjectInfo->reportedPointer(), target, name);
56 }
57
58 MemoryObjectType MemoryInstrumentation::getObjectType(MemoryObjectInfo* objectInfo)
59 {
60     return objectInfo->objectType();
61 }
62
63 void MemoryInstrumentation::callReportObjectInfo(MemoryObjectInfo* memoryObjectInfo, const void* pointer, MemoryObjectType objectType, size_t objectSize)
64 {
65     memoryObjectInfo->reportObjectInfo(pointer, objectType, objectSize);
66 }
67
68 void MemoryInstrumentation::reportLinkToBuffer(const void* owner, const void* buffer, MemoryObjectType ownerObjectType, size_t size, const char* nodeName, const char* edgeName)
69 {
70     MemoryObjectInfo memoryObjectInfo(this, ownerObjectType);
71     memoryObjectInfo.reportObjectInfo(buffer, ownerObjectType, size);
72     memoryObjectInfo.setName(nodeName);
73     m_client->reportLeaf(owner, memoryObjectInfo, edgeName);
74 }
75
76 MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase(MemoryObjectInfo* memoryObjectInfo)
77     : m_ownerObjectType(memoryObjectInfo->objectType())
78 {
79 #if DEBUG_POINTER_INSTRUMENTATION
80     m_callStackSize = s_maxCallStackSize;
81     WTFGetBacktrace(m_callStack, &m_callStackSize);
82 #endif
83 }
84
85 void MemoryInstrumentation::InstrumentedPointerBase::process(MemoryInstrumentation* memoryInstrumentation)
86 {
87     MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType);
88     const void* originalPointer = callReportMemoryUsage(&memoryObjectInfo);
89
90     const void* pointer = memoryObjectInfo.reportedPointer();
91     ASSERT(pointer);
92     if (pointer != originalPointer) {
93         memoryInstrumentation->m_client->reportBaseAddress(originalPointer, pointer);
94         if (memoryInstrumentation->visited(pointer))
95             return;
96     }
97     memoryInstrumentation->countObjectSize(pointer, memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
98     memoryInstrumentation->m_client->reportNode(memoryObjectInfo);
99     if (!memoryInstrumentation->checkCountedObject(pointer)) {
100 #if DEBUG_POINTER_INSTRUMENTATION
101         fputs("Unknown object counted:\n", stderr);
102         WTFPrintBacktrace(m_callStack, m_callStackSize);
103 #endif
104     }
105 }
106
107 void MemoryClassInfo::init(const void* pointer, MemoryObjectType objectType, size_t actualSize)
108 {
109     m_memoryObjectInfo->reportObjectInfo(pointer, objectType, actualSize);
110     m_memoryInstrumentation = m_memoryObjectInfo->memoryInstrumentation();
111     m_objectType = m_memoryObjectInfo->objectType();
112 }
113
114 void MemoryClassInfo::addRawBuffer(const void* const& buffer, size_t size, const char* nodeName, const char* edgeName)
115 {
116     m_memoryInstrumentation->addRawBuffer(m_memoryObjectInfo->reportedPointer(), buffer, m_objectType, size, nodeName, edgeName);
117 }
118
119 void MemoryClassInfo::addPrivateBuffer(size_t size, MemoryObjectType ownerObjectType, const char* nodeName, const char* edgeName)
120 {
121     if (!size)
122         return;
123     if (!ownerObjectType)
124         ownerObjectType = m_objectType;
125     m_memoryInstrumentation->countObjectSize(0, ownerObjectType, size);
126     m_memoryInstrumentation->reportLinkToBuffer(m_memoryObjectInfo->reportedPointer(), 0, ownerObjectType, size, nodeName, edgeName);
127 }
128
129 } // namespace WTF