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 37 HeapProfiler::HeapProfiler() 38 : snapshots_(new HeapSnapshotsCollection()), 39 next_snapshot_uid_(1) { 40 } 41 42 43 HeapProfiler::~HeapProfiler() { 44 delete snapshots_; 45 } 46 47 48 void HeapProfiler::ResetSnapshots() { 49 delete snapshots_; 50 snapshots_ = new HeapSnapshotsCollection(); 51 } 52 53 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 62 void HeapProfiler::TearDown() { 63 Isolate* isolate = Isolate::Current(); 64 delete isolate->heap_profiler(); 65 isolate->set_heap_profiler(NULL); 66 } 67 68 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 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 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 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 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 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 140 int HeapProfiler::GetSnapshotsCount() { 141 HeapProfiler* profiler = Isolate::Current()->heap_profiler(); 142 ASSERT(profiler != NULL); 143 return profiler->snapshots_->snapshots()->length(); 144 } 145 146 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 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 161 void HeapProfiler::DeleteAllSnapshots() { 162 HeapProfiler* profiler = Isolate::Current()->heap_profiler(); 163 ASSERT(profiler != NULL); 164 profiler->ResetSnapshots(); 165 } 166 167 168 void HeapProfiler::ObjectMoveEvent(Address from, Address to) { 169 snapshots_->ObjectMoveEvent(from, to); 170 } 171 172 173 } } // namespace v8::internal 174