1 // Copyright 2009-2010 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 "heap-profiler.h"
31 #include "profile-generator.h"
32
33 namespace v8 {
34 namespace internal {
35
36
HeapProfiler()37 HeapProfiler::HeapProfiler()
38 : snapshots_(new HeapSnapshotsCollection()),
39 next_snapshot_uid_(1) {
40 }
41
42
~HeapProfiler()43 HeapProfiler::~HeapProfiler() {
44 delete snapshots_;
45 }
46
47
ResetSnapshots()48 void HeapProfiler::ResetSnapshots() {
49 delete snapshots_;
50 snapshots_ = new HeapSnapshotsCollection();
51 }
52
53
SetUp()54 void HeapProfiler::SetUp() {
55 Isolate* isolate = Isolate::Current();
56 if (isolate->heap_profiler() == NULL) {
57 isolate->set_heap_profiler(new HeapProfiler());
58 }
59 }
60
61
TearDown()62 void HeapProfiler::TearDown() {
63 Isolate* isolate = Isolate::Current();
64 delete isolate->heap_profiler();
65 isolate->set_heap_profiler(NULL);
66 }
67
68
TakeSnapshot(const char * name,int type,v8::ActivityControl * control)69 HeapSnapshot* HeapProfiler::TakeSnapshot(const char* name,
70 int type,
71 v8::ActivityControl* control) {
72 ASSERT(Isolate::Current()->heap_profiler() != NULL);
73 return Isolate::Current()->heap_profiler()->TakeSnapshotImpl(name,
74 type,
75 control);
76 }
77
78
TakeSnapshot(String * name,int type,v8::ActivityControl * control)79 HeapSnapshot* HeapProfiler::TakeSnapshot(String* name,
80 int type,
81 v8::ActivityControl* control) {
82 ASSERT(Isolate::Current()->heap_profiler() != NULL);
83 return Isolate::Current()->heap_profiler()->TakeSnapshotImpl(name,
84 type,
85 control);
86 }
87
88
DefineWrapperClass(uint16_t class_id,v8::HeapProfiler::WrapperInfoCallback callback)89 void HeapProfiler::DefineWrapperClass(
90 uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback) {
91 ASSERT(class_id != v8::HeapProfiler::kPersistentHandleNoClassId);
92 if (wrapper_callbacks_.length() <= class_id) {
93 wrapper_callbacks_.AddBlock(
94 NULL, class_id - wrapper_callbacks_.length() + 1);
95 }
96 wrapper_callbacks_[class_id] = callback;
97 }
98
99
ExecuteWrapperClassCallback(uint16_t class_id,Object ** wrapper)100 v8::RetainedObjectInfo* HeapProfiler::ExecuteWrapperClassCallback(
101 uint16_t class_id, Object** wrapper) {
102 if (wrapper_callbacks_.length() <= class_id) return NULL;
103 return wrapper_callbacks_[class_id](
104 class_id, Utils::ToLocal(Handle<Object>(wrapper)));
105 }
106
107
TakeSnapshotImpl(const char * name,int type,v8::ActivityControl * control)108 HeapSnapshot* HeapProfiler::TakeSnapshotImpl(const char* name,
109 int type,
110 v8::ActivityControl* control) {
111 HeapSnapshot::Type s_type = static_cast<HeapSnapshot::Type>(type);
112 HeapSnapshot* result =
113 snapshots_->NewSnapshot(s_type, name, next_snapshot_uid_++);
114 bool generation_completed = true;
115 switch (s_type) {
116 case HeapSnapshot::kFull: {
117 HeapSnapshotGenerator generator(result, control);
118 generation_completed = generator.GenerateSnapshot();
119 break;
120 }
121 default:
122 UNREACHABLE();
123 }
124 if (!generation_completed) {
125 delete result;
126 result = NULL;
127 }
128 snapshots_->SnapshotGenerationFinished(result);
129 return result;
130 }
131
132
TakeSnapshotImpl(String * name,int type,v8::ActivityControl * control)133 HeapSnapshot* HeapProfiler::TakeSnapshotImpl(String* name,
134 int type,
135 v8::ActivityControl* control) {
136 return TakeSnapshotImpl(snapshots_->names()->GetName(name), type, control);
137 }
138
139
GetSnapshotsCount()140 int HeapProfiler::GetSnapshotsCount() {
141 HeapProfiler* profiler = Isolate::Current()->heap_profiler();
142 ASSERT(profiler != NULL);
143 return profiler->snapshots_->snapshots()->length();
144 }
145
146
GetSnapshot(int index)147 HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
148 HeapProfiler* profiler = Isolate::Current()->heap_profiler();
149 ASSERT(profiler != NULL);
150 return profiler->snapshots_->snapshots()->at(index);
151 }
152
153
FindSnapshot(unsigned uid)154 HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
155 HeapProfiler* profiler = Isolate::Current()->heap_profiler();
156 ASSERT(profiler != NULL);
157 return profiler->snapshots_->GetSnapshot(uid);
158 }
159
160
DeleteAllSnapshots()161 void HeapProfiler::DeleteAllSnapshots() {
162 HeapProfiler* profiler = Isolate::Current()->heap_profiler();
163 ASSERT(profiler != NULL);
164 profiler->ResetSnapshots();
165 }
166
167
ObjectMoveEvent(Address from,Address to)168 void HeapProfiler::ObjectMoveEvent(Address from, Address to) {
169 snapshots_->ObjectMoveEvent(from, to);
170 }
171
172
173 } } // namespace v8::internal
174