Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: src/allocation-tracker.cc

Issue 27227005: Record allocation stack traces (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "allocation-tracker.h"
31
32 #include "frames-inl.h"
33
34 namespace v8 {
35 namespace internal {
36
37 AllocationTraceNode::AllocationTraceNode(
38 AllocationTraceTree* tree, SnapshotObjectId shared_function_info_id)
39 : tree_(tree),
40 function_id_(shared_function_info_id),
41 total_size_(0),
42 allocation_count_(0),
43 id_(tree->next_node_id()) {
44 }
45
46
47 AllocationTraceNode::~AllocationTraceNode() {
48 }
49
50
51 AllocationTraceNode* AllocationTraceNode::FindChild(SnapshotObjectId id) {
52 for (int i = 0; i < children_.length(); i++) {
53 AllocationTraceNode* node = children_[i];
54 if (node->function_id() == id) return node;
55 }
56 return NULL;
57 }
58
59
60 AllocationTraceNode* AllocationTraceNode::FindOrAddChild(SnapshotObjectId id) {
61 AllocationTraceNode* child = FindChild(id);
62 if (child == NULL) {
63 child = new AllocationTraceNode(tree_, id);
64 children_.Add(child);
65 }
66 return child;
67 }
68
69
70 void AllocationTraceNode::AddAllocation(unsigned size) {
71 total_size_ += size;
72 ++allocation_count_;
73 }
74
75
76 void AllocationTraceNode::Print(int indent) {
77 OS::Print("%10u %10u %*c %u #%u",
78 total_size_, allocation_count_,
79 indent, ' ',
80 function_id_,
81 id_);
82 OS::Print("\n");
83 indent += 2;
84 for (int i = 0; i < children_.length(); i++) {
85 children_[i]->Print(indent);
86 }
87 }
88
89
90 AllocationTraceTree::AllocationTraceTree()
91 : next_node_id_(1),
92 root_(this, 0) {
93 }
94
95
96 AllocationTraceTree::~AllocationTraceTree() {
97 }
98
99
100 AllocationTraceNode* AllocationTraceTree::AddPathFromEnd(
101 const Vector<SnapshotObjectId>& path) {
102 AllocationTraceNode* node = root();
103 for (SnapshotObjectId* entry = path.start() + path.length() - 1;
104 entry != path.start() - 1;
105 --entry) {
106 node = node->FindOrAddChild(*entry);
107 }
108 return node;
109 }
110
111
112 void AllocationTraceTree::Print() {
113 OS::Print("[AllocationTraceTree:]\n");
114 OS::Print("Total size | Allocation count | Function id | id\n");
115 root()->Print(0);
116 }
117
118 void AllocationTracker::DeleteUnresolvedLocation(
119 UnresolvedLocation** location) {
120 delete *location;
121 }
122
123
124 static bool AddressesMatch(void* key1, void* key2) {
125 return key1 == key2;
126 }
127
128
129 AllocationTracker::AllocationTracker(
130 HeapObjectsMap* ids, StringsStorage* names)
131 : ids_(ids),
132 names_(names),
133 id_to_function_info_(AddressesMatch) {
134 }
135
136
137 AllocationTracker::~AllocationTracker() {
138 unresolved_locations_.Iterate(DeleteUnresolvedLocation);
139 }
140
141
142 void AllocationTracker::PrepareForSerialization() {
143 List<UnresolvedLocation*> copy(unresolved_locations_.length());
144 copy.AddAll(unresolved_locations_);
145 unresolved_locations_.Clear();
146 for (int i = 0; i < copy.length(); i++) {
147 copy[i]->Resolve();
148 delete copy[i];
149 }
150 }
151
152
153 void AllocationTracker::NewObjectEvent(Address addr, int size) {
154 DisallowHeapAllocation no_allocation;
155 Isolate* isolate = ids_->heap()->isolate();
156 int length = 0;
157 StackTraceFrameIterator it(isolate);
158 while (!it.done() && length < kMaxAllocationTraceLength) {
159 JavaScriptFrame* frame = it.frame();
160 SharedFunctionInfo* shared = frame->function()->shared();
161 SnapshotObjectId id = ids_->FindEntry(shared->address());
162 allocation_trace_buffer_[length++] = id;
163 AddFunctionInfo(shared, id);
164 it.Advance();
165 }
166 AllocationTraceNode* top_node = allocation_traces_.AddPathFromEnd(
167 Vector<SnapshotObjectId>(allocation_trace_buffer_, length));
168 top_node->AddAllocation(size);
169 }
170
171
172 static uint32_t SnapshotObjectIdHash(SnapshotObjectId id) {
173 return ComputeIntegerHash(static_cast<uint32_t>(id),
174 v8::internal::kZeroHashSeed);
175 }
176
177
178 void AllocationTracker::AddFunctionInfo(SharedFunctionInfo* shared,
179 SnapshotObjectId id) {
180 HashMap::Entry* entry = id_to_function_info_.Lookup(
181 reinterpret_cast<void*>(id), SnapshotObjectIdHash(id), true);
182 if (entry->value == NULL) {
183 FunctionInfo* info = new FunctionInfo();
184 info->name = names_->GetFunctionName(shared->DebugName());
185 if (shared->script()->IsScript()) {
186 Script* script = Script::cast(shared->script());
187 if (script->name()->IsName()) {
188 Name* name = Name::cast(script->name());
189 info->script_name = names_->GetFunctionName(name);
190 } else {
191 script->name()->PrintLn();
192 printf("script->name is not a name\n");
loislo 2013/10/16 15:14:08 please remove this
yurys 2013/10/17 15:27:35 Done.
193 }
194 info->script_id = script->id()->value();
195 // Converting start offset into line and column may cause heap allocations .
loislo 2013/10/16 15:14:08 80 symbols
yurys 2013/10/17 15:27:35 Done.
196 unresolved_locations_.Add(new UnresolvedLocation(
197 script,
198 shared->start_position(),
199 info));
200 }
201 entry->value = info;
202 }
203 }
204
205
206 AllocationTracker::UnresolvedLocation::UnresolvedLocation(
207 Script* script, int start, FunctionInfo* info)
208 : start_position_(start),
209 info_(info) {
210 script_ = script->GetIsolate()->global_handles()->Create(script);
211 GlobalHandles::MakeWeak(
212 reinterpret_cast<Object**>(script_.location()),
213 this, &HandleWeakScript);
214 }
215
216
217 AllocationTracker::UnresolvedLocation::~UnresolvedLocation() {
218 if (!script_.is_null()) {
219 script_->GetIsolate()->global_handles()->Destroy(
220 reinterpret_cast<Object**>(script_.location()));
221 }
222 }
223
224
225 void AllocationTracker::UnresolvedLocation::Resolve() {
226 if (script_.is_null()) return;
227 info_->line = GetScriptLineNumber(script_, start_position_);
228 info_->column = GetScriptColumnNumber(script_, start_position_);
229 }
230
231
232 void AllocationTracker::UnresolvedLocation::HandleWeakScript(
233 v8::Isolate* isolate,
234 v8::Persistent<v8::Value>* obj,
235 void* data) {
236 UnresolvedLocation* location = reinterpret_cast<UnresolvedLocation*>(data);
237 location->script_ = Handle<Script>::null();
238 obj->Dispose();
239 }
240
241
242 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698