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

Side by Side Diff: src/profile-generator.cc

Issue 7082012: Heap profiler: fetch document.URL of global objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Style fix Created 9 years, 7 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
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 if (!obj->IsHeapObject()) return; 1595 if (!obj->IsHeapObject()) return;
1596 HeapObject* object = HeapObject::cast(obj); 1596 HeapObject* object = HeapObject::cast(obj);
1597 HashMap::Entry* cache_entry = 1597 HashMap::Entry* cache_entry =
1598 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); 1598 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1599 if (cache_entry->value == NULL) { 1599 if (cache_entry->value == NULL) {
1600 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; 1600 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 1604
1605 const char* HeapObjectsSet::GetTag(Object* obj) {
1606 HeapObject* object = HeapObject::cast(obj);
1607 HashMap::Entry* cache_entry =
1608 entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
1609 if (cache_entry != NULL
1610 && cache_entry->value != HeapEntriesMap::kHeapEntryPlaceholder) {
1611 return reinterpret_cast<const char*>(cache_entry->value);
1612 } else {
1613 return NULL;
1614 }
1615 }
1616
1617
1618 void HeapObjectsSet::SetTag(Object* obj, const char* tag) {
1619 if (!obj->IsHeapObject()) return;
1620 HeapObject* object = HeapObject::cast(obj);
1621 HashMap::Entry* cache_entry =
1622 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1623 cache_entry->value = const_cast<char*>(tag);
1624 }
1625
1626
1605 HeapObject *const V8HeapExplorer::kInternalRootObject = 1627 HeapObject *const V8HeapExplorer::kInternalRootObject =
1606 reinterpret_cast<HeapObject*>( 1628 reinterpret_cast<HeapObject*>(
1607 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId)); 1629 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
1608 HeapObject *const V8HeapExplorer::kGcRootsObject = 1630 HeapObject *const V8HeapExplorer::kGcRootsObject =
1609 reinterpret_cast<HeapObject*>( 1631 reinterpret_cast<HeapObject*>(
1610 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId)); 1632 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId));
1611 1633
1612 1634
1613 V8HeapExplorer::V8HeapExplorer( 1635 V8HeapExplorer::V8HeapExplorer(
1614 HeapSnapshot* snapshot, 1636 HeapSnapshot* snapshot,
(...skipping 17 matching lines...) Expand all
1632 1654
1633 1655
1634 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, 1656 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1635 int children_count, 1657 int children_count,
1636 int retainers_count) { 1658 int retainers_count) {
1637 if (object == kInternalRootObject) { 1659 if (object == kInternalRootObject) {
1638 ASSERT(retainers_count == 0); 1660 ASSERT(retainers_count == 0);
1639 return snapshot_->AddRootEntry(children_count); 1661 return snapshot_->AddRootEntry(children_count);
1640 } else if (object == kGcRootsObject) { 1662 } else if (object == kGcRootsObject) {
1641 return snapshot_->AddGcRootsEntry(children_count, retainers_count); 1663 return snapshot_->AddGcRootsEntry(children_count, retainers_count);
1664 } else if (object->IsJSGlobalObject()) {
1665 const char* tag = objects_tags_.GetTag(object);
1666 const char* name = collection_->names()->GetName(
1667 GetConstructorNameForHeapProfile(
1668 JSObject::cast(object)));
Vitaly Repeshko 2011/05/29 23:01:34 nit: Fits on the previous line?
mnaganov (inactive) 2011/05/30 14:20:42 Done.
1669 if (tag != NULL) {
1670 name = collection_->names()->GetFormatted("%s / %s", name, tag);
1671 }
1672 return AddEntry(object,
1673 HeapEntry::kObject,
1674 name,
1675 children_count,
1676 retainers_count);
1642 } else if (object->IsJSFunction()) { 1677 } else if (object->IsJSFunction()) {
1643 JSFunction* func = JSFunction::cast(object); 1678 JSFunction* func = JSFunction::cast(object);
1644 SharedFunctionInfo* shared = func->shared(); 1679 SharedFunctionInfo* shared = func->shared();
1645 return AddEntry(object, 1680 return AddEntry(object,
1646 HeapEntry::kClosure, 1681 HeapEntry::kClosure,
1647 collection_->names()->GetName(String::cast(shared->name())), 1682 collection_->names()->GetName(String::cast(shared->name())),
1648 children_count, 1683 children_count,
1649 retainers_count); 1684 retainers_count);
1650 } else if (object->IsJSRegExp()) { 1685 } else if (object->IsJSRegExp()) {
1651 JSRegExp* re = JSRegExp::cast(object); 1686 JSRegExp* re = JSRegExp::cast(object);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); 1808 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
1774 } 1809 }
1775 } 1810 }
1776 static void MarkVisitedField(HeapObject* obj, int offset) { 1811 static void MarkVisitedField(HeapObject* obj, int offset) {
1777 if (offset < 0) return; 1812 if (offset < 0) return;
1778 Address field = obj->address() + offset; 1813 Address field = obj->address() + offset;
1779 ASSERT(!Memory::Object_at(field)->IsFailure()); 1814 ASSERT(!Memory::Object_at(field)->IsFailure());
1780 ASSERT(Memory::Object_at(field)->IsHeapObject()); 1815 ASSERT(Memory::Object_at(field)->IsHeapObject());
1781 *field |= kFailureTag; 1816 *field |= kFailureTag;
1782 } 1817 }
1818
1783 private: 1819 private:
1784 bool CheckVisitedAndUnmark(Object** field) { 1820 bool CheckVisitedAndUnmark(Object** field) {
1785 if ((*field)->IsFailure()) { 1821 if ((*field)->IsFailure()) {
1786 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask; 1822 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
1787 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag); 1823 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
1788 ASSERT((*field)->IsHeapObject()); 1824 ASSERT((*field)->IsHeapObject());
1789 return true; 1825 return true;
1790 } 1826 }
1791 return false; 1827 return false;
1792 } 1828 }
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 HeapEntry* child_entry = GetEntry(child_obj); 2235 HeapEntry* child_entry = GetEntry(child_obj);
2200 if (child_entry != NULL) { 2236 if (child_entry != NULL) {
2201 filler_->SetIndexedAutoIndexReference( 2237 filler_->SetIndexedAutoIndexReference(
2202 HeapGraphEdge::kElement, 2238 HeapGraphEdge::kElement,
2203 kGcRootsObject, snapshot_->gc_roots(), 2239 kGcRootsObject, snapshot_->gc_roots(),
2204 child_obj, child_entry); 2240 child_obj, child_entry);
2205 } 2241 }
2206 } 2242 }
2207 2243
2208 2244
2245 class GlobalObjectsCounter : public ObjectVisitor {
2246 public:
2247 GlobalObjectsCounter() : count_(0) {}
2248 void VisitPointers(Object** start, Object** end) {
Vitaly Repeshko 2011/05/29 23:01:34 nit: virtual
mnaganov (inactive) 2011/05/30 14:20:42 Done.
2249 for (Object** p = start; p < end; p++) {
2250 if ((*p)->IsGlobalContext())
2251 ++count_;
2252 }
2253 }
2254 int count() { return count_; }
2255
2256 private:
2257 int count_;
2258 };
2259
2260
2261 class GlobalObjectsEnumerator : public ObjectVisitor {
2262 public:
2263 explicit GlobalObjectsEnumerator(int length)
2264 : length_(length),
2265 count_(0),
2266 objects_(NewArray<Handle<JSGlobalObject> >(length)) {}
2267 ~GlobalObjectsEnumerator() {
2268 DeleteArray(objects_);
2269 }
2270 void VisitPointers(Object** start, Object** end) {
Vitaly Repeshko 2011/05/29 23:01:34 nit: virtual
mnaganov (inactive) 2011/05/30 14:20:42 Done.
2271 for (Object** p = start; count_ < length_ && p < end; p++) {
2272 if ((*p)->IsGlobalContext()) {
2273 Context* context = Context::cast(*p);
2274 JSObject* proxy = context->global_proxy();
2275 if (proxy->IsJSGlobalProxy()) {
Vitaly Repeshko 2011/05/29 23:01:34 Given that this loop has more conditions than its
mnaganov (inactive) 2011/05/30 14:20:42 Fixed by eliminating the counter class.
2276 Object* global = proxy->map()->prototype();
2277 if (global->IsJSGlobalObject())
Vitaly Repeshko 2011/05/29 23:01:34 nit: {}
mnaganov (inactive) 2011/05/30 14:20:42 Done.
2278 objects_[count_++] =
2279 Handle<JSGlobalObject>(JSGlobalObject::cast(global));
2280 }
2281 }
2282 }
2283 }
2284 int count() { return count_; }
2285 Handle<JSGlobalObject>* objects() { return objects_; }
2286
2287 private:
2288 const int length_;
2289 int count_;
2290 Handle<JSGlobalObject>* objects_;
Vitaly Repeshko 2011/05/29 23:01:34 Can we use a growable collection of handles (e.g.
mnaganov (inactive) 2011/05/30 14:20:42 Sure. Sorry, I forgot about their existence.
2291 };
2292
2293
2294 // Modifies heap. Must not be run during heap traversal.
2295 void V8HeapExplorer::TagGlobalObjects() {
Vitaly Repeshko 2011/05/29 23:01:34 Random idea. I don't know how flexible we want to
mnaganov (inactive) 2011/05/30 14:20:42 Let's discuss it later.
2296 Isolate* isolate = Isolate::Current();
2297 GlobalObjectsCounter counter;
2298 isolate->global_handles()->IterateAllRoots(&counter);
2299 GlobalObjectsEnumerator enumerator(counter.count());
2300 isolate->global_handles()->IterateAllRoots(&enumerator);
2301 Handle<String> document_string =
2302 isolate->factory()->NewStringFromAscii(CStrVector("document"));
2303 Handle<String> url_string =
2304 isolate->factory()->NewStringFromAscii(CStrVector("URL"));
2305 const char** urls = NewArray<const char*>(counter.count());
2306 for (int i = 0; i < counter.count(); ++i) {
2307 urls[i] = NULL;
2308 Handle<JSGlobalObject>& go = enumerator.objects()[i];
Vitaly Repeshko 2011/05/29 23:01:34 Reference is not needed here. "go" is too short.
mnaganov (inactive) 2011/05/30 14:20:42 Removed ref. s/go/global_obj/
2309 Object* obj_document = go->GetPropertyNoExceptionThrown(*document_string);
Vitaly Repeshko 2011/05/29 23:01:34 This is not safe, because it asserts on failure/ex
mnaganov (inactive) 2011/05/30 14:20:42 Done.
2310 if (obj_document->IsJSObject()) {
2311 JSObject* document = JSObject::cast(obj_document);
2312 Object* obj_url = document->GetProperty(*url_string)->ToObjectUnchecked();
Vitaly Repeshko 2011/05/29 23:01:34 Also asserts on failure/exception.
mnaganov (inactive) 2011/05/30 14:20:42 Done.
2313 if (obj_url->IsString()) {
2314 urls[i] = collection_->names()->GetName(String::cast(obj_url));
2315 }
2316 }
2317 }
2318
2319 AssertNoAllocation no_allocation;
2320 for (int i = 0; i < counter.count(); ++i) {
2321 objects_tags_.SetTag(*enumerator.objects()[i], urls[i]);
2322 }
2323
2324 DeleteArray(urls);
2325 }
2326
2327
2209 class GlobalHandlesExtractor : public ObjectVisitor { 2328 class GlobalHandlesExtractor : public ObjectVisitor {
2210 public: 2329 public:
2211 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer) 2330 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer)
2212 : explorer_(explorer) {} 2331 : explorer_(explorer) {}
2213 virtual ~GlobalHandlesExtractor() {} 2332 virtual ~GlobalHandlesExtractor() {}
2214 virtual void VisitPointers(Object** start, Object** end) { 2333 virtual void VisitPointers(Object** start, Object** end) {
2215 UNREACHABLE(); 2334 UNREACHABLE();
2216 } 2335 }
2217 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) { 2336 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {
2218 explorer_->VisitSubtreeWrapper(p, class_id); 2337 explorer_->VisitSubtreeWrapper(p, class_id);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 HeapEntry*) { 2560 HeapEntry*) {
2442 entries_->CountReference(parent_ptr, child_ptr); 2561 entries_->CountReference(parent_ptr, child_ptr);
2443 } 2562 }
2444 void SetNamedAutoIndexReference(HeapGraphEdge::Type, 2563 void SetNamedAutoIndexReference(HeapGraphEdge::Type,
2445 HeapThing parent_ptr, 2564 HeapThing parent_ptr,
2446 HeapEntry*, 2565 HeapEntry*,
2447 HeapThing child_ptr, 2566 HeapThing child_ptr,
2448 HeapEntry*) { 2567 HeapEntry*) {
2449 entries_->CountReference(parent_ptr, child_ptr); 2568 entries_->CountReference(parent_ptr, child_ptr);
2450 } 2569 }
2570
2451 private: 2571 private:
2452 HeapEntriesMap* entries_; 2572 HeapEntriesMap* entries_;
2453 }; 2573 };
2454 2574
2455 2575
2456 class SnapshotFiller : public SnapshotFillerInterface { 2576 class SnapshotFiller : public SnapshotFillerInterface {
2457 public: 2577 public:
2458 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) 2578 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2459 : snapshot_(snapshot), 2579 : snapshot_(snapshot),
2460 collection_(snapshot->collection()), 2580 collection_(snapshot->collection()),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2512 HeapEntry* child_entry) { 2632 HeapEntry* child_entry) {
2513 int child_index, retainer_index; 2633 int child_index, retainer_index;
2514 entries_->CountReference( 2634 entries_->CountReference(
2515 parent_ptr, child_ptr, &child_index, &retainer_index); 2635 parent_ptr, child_ptr, &child_index, &retainer_index);
2516 parent_entry->SetNamedReference(type, 2636 parent_entry->SetNamedReference(type,
2517 child_index, 2637 child_index,
2518 collection_->names()->GetName(child_index + 1), 2638 collection_->names()->GetName(child_index + 1),
2519 child_entry, 2639 child_entry,
2520 retainer_index); 2640 retainer_index);
2521 } 2641 }
2642
2522 private: 2643 private:
2523 HeapSnapshot* snapshot_; 2644 HeapSnapshot* snapshot_;
2524 HeapSnapshotsCollection* collection_; 2645 HeapSnapshotsCollection* collection_;
2525 HeapEntriesMap* entries_; 2646 HeapEntriesMap* entries_;
2526 }; 2647 };
2527 2648
2528 2649
2529 bool HeapSnapshotGenerator::GenerateSnapshot() { 2650 bool HeapSnapshotGenerator::GenerateSnapshot() {
2651 v8_heap_explorer_.TagGlobalObjects();
2652
2530 AssertNoAllocation no_alloc; 2653 AssertNoAllocation no_alloc;
2531 2654
2532 SetProgressTotal(4); // 2 passes + dominators + sizes. 2655 SetProgressTotal(4); // 2 passes + dominators + sizes.
2533 2656
2534 // Pass 1. Iterate heap contents to count entries and references. 2657 // Pass 1. Iterate heap contents to count entries and references.
2535 if (!CountEntriesAndReferences()) return false; 2658 if (!CountEntriesAndReferences()) return false;
2536 2659
2537 // Allocate and fill entries in the snapshot, allocate references. 2660 // Allocate and fill entries in the snapshot, allocate references.
2538 snapshot_->AllocateEntries(entries_.entries_count(), 2661 snapshot_->AllocateEntries(entries_.entries_count(),
2539 entries_.total_children_count(), 2662 entries_.total_children_count(),
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
3089 3212
3090 3213
3091 String* GetConstructorNameForHeapProfile(JSObject* object) { 3214 String* GetConstructorNameForHeapProfile(JSObject* object) {
3092 if (object->IsJSFunction()) return HEAP->closure_symbol(); 3215 if (object->IsJSFunction()) return HEAP->closure_symbol();
3093 return object->constructor_name(); 3216 return object->constructor_name();
3094 } 3217 }
3095 3218
3096 } } // namespace v8::internal 3219 } } // namespace v8::internal
3097 3220
3098 #endif // ENABLE_LOGGING_AND_PROFILING 3221 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698