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 33namespace v8 { 34namespace internal { 35 36 37HeapProfiler::HeapProfiler() 38 : snapshots_(new HeapSnapshotsCollection()), 39 next_snapshot_uid_(1) { 40} 41 42 43HeapProfiler::~HeapProfiler() { 44 delete snapshots_; 45} 46 47 48void HeapProfiler::ResetSnapshots() { 49 delete snapshots_; 50 snapshots_ = new HeapSnapshotsCollection(); 51} 52 53 54void HeapProfiler::SetUp() { 55 Isolate* isolate = Isolate::Current(); 56 if (isolate->heap_profiler() == NULL) { 57 isolate->set_heap_profiler(new HeapProfiler()); 58 } 59} 60 61 62void HeapProfiler::TearDown() { 63 Isolate* isolate = Isolate::Current(); 64 delete isolate->heap_profiler(); 65 isolate->set_heap_profiler(NULL); 66} 67 68 69HeapSnapshot* 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 79HeapSnapshot* 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 89void 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 100v8::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 108HeapSnapshot* 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 133HeapSnapshot* HeapProfiler::TakeSnapshotImpl(String* name, 134 int type, 135 v8::ActivityControl* control) { 136 return TakeSnapshotImpl(snapshots_->names()->GetName(name), type, control); 137} 138 139 140int HeapProfiler::GetSnapshotsCount() { 141 HeapProfiler* profiler = Isolate::Current()->heap_profiler(); 142 ASSERT(profiler != NULL); 143 return profiler->snapshots_->snapshots()->length(); 144} 145 146 147HeapSnapshot* 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 154HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) { 155 HeapProfiler* profiler = Isolate::Current()->heap_profiler(); 156 ASSERT(profiler != NULL); 157 return profiler->snapshots_->GetSnapshot(uid); 158} 159 160 161void HeapProfiler::DeleteAllSnapshots() { 162 HeapProfiler* profiler = Isolate::Current()->heap_profiler(); 163 ASSERT(profiler != NULL); 164 profiler->ResetSnapshots(); 165} 166 167 168void HeapProfiler::ObjectMoveEvent(Address from, Address to) { 169 snapshots_->ObjectMoveEvent(from, to); 170} 171 172 173} } // namespace v8::internal 174