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

Side by Side Diff: src/profiler/heap-snapshot-generator.cc

Issue 1476413002: Don't intrusively mark in the heap snapshot generator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « src/profiler/heap-snapshot-generator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/profiler/heap-snapshot-generator.h" 5 #include "src/profiler/heap-snapshot-generator.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/debug/debug.h" 9 #include "src/debug/debug.h"
10 #include "src/objects-body-descriptors.h" 10 #include "src/objects-body-descriptors.h"
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 obj != NULL; 981 obj != NULL;
982 obj = iterator->next()) { 982 obj = iterator->next()) {
983 objects_count++; 983 objects_count++;
984 } 984 }
985 return objects_count; 985 return objects_count;
986 } 986 }
987 987
988 988
989 class IndexedReferencesExtractor : public ObjectVisitor { 989 class IndexedReferencesExtractor : public ObjectVisitor {
990 public: 990 public:
991 IndexedReferencesExtractor(V8HeapExplorer* generator, 991 IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject* parent_obj,
992 HeapObject* parent_obj,
993 int parent) 992 int parent)
994 : generator_(generator), 993 : generator_(generator),
995 parent_obj_(parent_obj), 994 parent_obj_(parent_obj),
995 parent_start_(HeapObject::RawField(parent_obj_, 0)),
996 parent_end_(HeapObject::RawField(parent_obj_, parent_obj_->Size())),
996 parent_(parent), 997 parent_(parent),
997 next_index_(0) { 998 next_index_(0) {}
998 }
999 void VisitCodeEntry(Address entry_address) override { 999 void VisitCodeEntry(Address entry_address) override {
1000 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); 1000 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
1001 generator_->SetInternalReference(parent_obj_, parent_, "code", code); 1001 generator_->SetInternalReference(parent_obj_, parent_, "code", code);
1002 generator_->TagCodeObject(code); 1002 generator_->TagCodeObject(code);
1003 } 1003 }
1004 void VisitPointers(Object** start, Object** end) override { 1004 void VisitPointers(Object** start, Object** end) override {
1005 for (Object** p = start; p < end; p++) { 1005 for (Object** p = start; p < end; p++) {
1006 intptr_t index =
1007 static_cast<intptr_t>(p - HeapObject::RawField(parent_obj_, 0));
1006 ++next_index_; 1008 ++next_index_;
1007 if (CheckVisitedAndUnmark(p)) continue; 1009 // |p| could be outside of the object, e.g., while visiting RelocInfo of
1010 // code objects.
1011 if (p >= parent_start_ && p < parent_end_ && generator_->marks_[index]) {
1012 generator_->marks_[index] = false;
1013 continue;
1014 }
1008 generator_->SetHiddenReference(parent_obj_, parent_, next_index_, *p); 1015 generator_->SetHiddenReference(parent_obj_, parent_, next_index_, *p);
1009 } 1016 }
1010 } 1017 }
1011 static void MarkVisitedField(HeapObject* obj, int offset) {
1012 if (offset < 0) return;
1013 Address field = obj->address() + offset;
1014 DCHECK(Memory::Object_at(field)->IsHeapObject());
1015 intptr_t p = reinterpret_cast<intptr_t>(Memory::Object_at(field));
1016 DCHECK(!IsMarked(p));
1017 intptr_t p_tagged = p | kTag;
1018 Memory::Object_at(field) = reinterpret_cast<Object*>(p_tagged);
1019 }
1020 1018
1021 private: 1019 private:
1022 bool CheckVisitedAndUnmark(Object** field) {
1023 intptr_t p = reinterpret_cast<intptr_t>(*field);
1024 if (IsMarked(p)) {
1025 intptr_t p_untagged = (p & ~kTaggingMask) | kHeapObjectTag;
1026 *field = reinterpret_cast<Object*>(p_untagged);
1027 DCHECK((*field)->IsHeapObject());
1028 return true;
1029 }
1030 return false;
1031 }
1032
1033 static const intptr_t kTaggingMask = 3;
1034 static const intptr_t kTag = 3;
1035
1036 static bool IsMarked(intptr_t p) { return (p & kTaggingMask) == kTag; }
1037
1038 V8HeapExplorer* generator_; 1020 V8HeapExplorer* generator_;
1039 HeapObject* parent_obj_; 1021 HeapObject* parent_obj_;
1022 Object** parent_start_;
1023 Object** parent_end_;
1040 int parent_; 1024 int parent_;
1041 int next_index_; 1025 int next_index_;
1042 }; 1026 };
1043 1027
1044 1028
1045 bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) { 1029 bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) {
1046 if (obj->IsFixedArray()) return false; // FixedArrays are processed on pass 2 1030 if (obj->IsFixedArray()) return false; // FixedArrays are processed on pass 2
1047 1031
1048 if (obj->IsJSGlobalProxy()) { 1032 if (obj->IsJSGlobalProxy()) {
1049 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj)); 1033 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj));
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 bool V8HeapExplorer::IterateAndExtractSinglePass() { 1848 bool V8HeapExplorer::IterateAndExtractSinglePass() {
1865 // Now iterate the whole heap. 1849 // Now iterate the whole heap.
1866 bool interrupted = false; 1850 bool interrupted = false;
1867 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); 1851 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable);
1868 // Heap iteration with filtering must be finished in any case. 1852 // Heap iteration with filtering must be finished in any case.
1869 for (HeapObject* obj = iterator.next(); 1853 for (HeapObject* obj = iterator.next();
1870 obj != NULL; 1854 obj != NULL;
1871 obj = iterator.next(), progress_->ProgressStep()) { 1855 obj = iterator.next(), progress_->ProgressStep()) {
1872 if (interrupted) continue; 1856 if (interrupted) continue;
1873 1857
1858 size_t max_pointer = obj->Size() / kPointerSize;
1859 if (max_pointer > marks_.size()) {
1860 // Clear the current bits.
1861 std::vector<bool>().swap(marks_);
1862 // Reallocate to right size.
1863 marks_.resize(max_pointer, false);
1864 }
1865
1874 HeapEntry* heap_entry = GetEntry(obj); 1866 HeapEntry* heap_entry = GetEntry(obj);
1875 int entry = heap_entry->index(); 1867 int entry = heap_entry->index();
1876 if ((this->*extractor)(entry, obj)) { 1868 if ((this->*extractor)(entry, obj)) {
1877 SetInternalReference(obj, entry, 1869 SetInternalReference(obj, entry,
1878 "map", obj->map(), HeapObject::kMapOffset); 1870 "map", obj->map(), HeapObject::kMapOffset);
1879 // Extract unvisited fields as hidden references and restore tags 1871 // Extract unvisited fields as hidden references and restore tags
1880 // of visited fields. 1872 // of visited fields.
1881 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1873 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1882 obj->Iterate(&refs_extractor); 1874 obj->Iterate(&refs_extractor);
1883 } 1875 }
(...skipping 24 matching lines...) Expand all
1908 String* reference_name, 1900 String* reference_name,
1909 Object* child_obj, 1901 Object* child_obj,
1910 int field_offset) { 1902 int field_offset) {
1911 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 1903 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1912 HeapEntry* child_entry = GetEntry(child_obj); 1904 HeapEntry* child_entry = GetEntry(child_obj);
1913 if (child_entry != NULL) { 1905 if (child_entry != NULL) {
1914 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 1906 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
1915 parent_entry, 1907 parent_entry,
1916 names_->GetName(reference_name), 1908 names_->GetName(reference_name),
1917 child_entry); 1909 child_entry);
1918 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1910 MarkVisitedField(parent_obj, field_offset);
1919 } 1911 }
1920 } 1912 }
1921 1913
1922 1914
1915 void V8HeapExplorer::MarkVisitedField(HeapObject* obj, int offset) {
1916 if (offset < 0) return;
1917 int index = offset / kPointerSize;
1918 DCHECK(!marks_[index]);
1919 marks_[index] = true;
1920 }
1921
1922
1923 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, 1923 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
1924 int parent_entry, 1924 int parent_entry,
1925 const char* reference_name, 1925 const char* reference_name,
1926 Object* child_obj) { 1926 Object* child_obj) {
1927 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 1927 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1928 HeapEntry* child_entry = GetEntry(child_obj); 1928 HeapEntry* child_entry = GetEntry(child_obj);
1929 if (child_entry != NULL) { 1929 if (child_entry != NULL) {
1930 filler_->SetNamedReference(HeapGraphEdge::kShortcut, 1930 filler_->SetNamedReference(HeapGraphEdge::kShortcut,
1931 parent_entry, 1931 parent_entry,
1932 reference_name, 1932 reference_name,
(...skipping 24 matching lines...) Expand all
1957 int field_offset) { 1957 int field_offset) {
1958 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 1958 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1959 HeapEntry* child_entry = GetEntry(child_obj); 1959 HeapEntry* child_entry = GetEntry(child_obj);
1960 if (child_entry == NULL) return; 1960 if (child_entry == NULL) return;
1961 if (IsEssentialObject(child_obj)) { 1961 if (IsEssentialObject(child_obj)) {
1962 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1962 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1963 parent_entry, 1963 parent_entry,
1964 reference_name, 1964 reference_name,
1965 child_entry); 1965 child_entry);
1966 } 1966 }
1967 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1967 MarkVisitedField(parent_obj, field_offset);
1968 } 1968 }
1969 1969
1970 1970
1971 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, 1971 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
1972 int parent_entry, 1972 int parent_entry,
1973 int index, 1973 int index,
1974 Object* child_obj, 1974 Object* child_obj,
1975 int field_offset) { 1975 int field_offset) {
1976 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 1976 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1977 HeapEntry* child_entry = GetEntry(child_obj); 1977 HeapEntry* child_entry = GetEntry(child_obj);
1978 if (child_entry == NULL) return; 1978 if (child_entry == NULL) return;
1979 if (IsEssentialObject(child_obj)) { 1979 if (IsEssentialObject(child_obj)) {
1980 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1980 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1981 parent_entry, 1981 parent_entry,
1982 names_->GetName(index), 1982 names_->GetName(index),
1983 child_entry); 1983 child_entry);
1984 } 1984 }
1985 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1985 MarkVisitedField(parent_obj, field_offset);
1986 } 1986 }
1987 1987
1988 1988
1989 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, 1989 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
1990 int parent_entry, 1990 int parent_entry,
1991 int index, 1991 int index,
1992 Object* child_obj) { 1992 Object* child_obj) {
1993 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 1993 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1994 HeapEntry* child_entry = GetEntry(child_obj); 1994 HeapEntry* child_entry = GetEntry(child_obj);
1995 if (child_entry != NULL && IsEssentialObject(child_obj)) { 1995 if (child_entry != NULL && IsEssentialObject(child_obj)) {
(...skipping 12 matching lines...) Expand all
2008 int field_offset) { 2008 int field_offset) {
2009 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 2009 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2010 HeapEntry* child_entry = GetEntry(child_obj); 2010 HeapEntry* child_entry = GetEntry(child_obj);
2011 if (child_entry == NULL) return; 2011 if (child_entry == NULL) return;
2012 if (IsEssentialObject(child_obj)) { 2012 if (IsEssentialObject(child_obj)) {
2013 filler_->SetNamedReference(HeapGraphEdge::kWeak, 2013 filler_->SetNamedReference(HeapGraphEdge::kWeak,
2014 parent_entry, 2014 parent_entry,
2015 reference_name, 2015 reference_name,
2016 child_entry); 2016 child_entry);
2017 } 2017 }
2018 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2018 MarkVisitedField(parent_obj, field_offset);
2019 } 2019 }
2020 2020
2021 2021
2022 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, 2022 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
2023 int parent_entry, 2023 int parent_entry,
2024 int index, 2024 int index,
2025 Object* child_obj, 2025 Object* child_obj,
2026 int field_offset) { 2026 int field_offset) {
2027 DCHECK(parent_entry == GetEntry(parent_obj)->index()); 2027 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2028 HeapEntry* child_entry = GetEntry(child_obj); 2028 HeapEntry* child_entry = GetEntry(child_obj);
2029 if (child_entry == NULL) return; 2029 if (child_entry == NULL) return;
2030 if (IsEssentialObject(child_obj)) { 2030 if (IsEssentialObject(child_obj)) {
2031 filler_->SetNamedReference(HeapGraphEdge::kWeak, 2031 filler_->SetNamedReference(HeapGraphEdge::kWeak,
2032 parent_entry, 2032 parent_entry,
2033 names_->GetFormatted("%d", index), 2033 names_->GetFormatted("%d", index),
2034 child_entry); 2034 child_entry);
2035 } 2035 }
2036 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2036 MarkVisitedField(parent_obj, field_offset);
2037 } 2037 }
2038 2038
2039 2039
2040 void V8HeapExplorer::SetDataOrAccessorPropertyReference( 2040 void V8HeapExplorer::SetDataOrAccessorPropertyReference(
2041 PropertyKind kind, JSObject* parent_obj, int parent_entry, 2041 PropertyKind kind, JSObject* parent_obj, int parent_entry,
2042 Name* reference_name, Object* child_obj, const char* name_format_string, 2042 Name* reference_name, Object* child_obj, const char* name_format_string,
2043 int field_offset) { 2043 int field_offset) {
2044 if (kind == kAccessor) { 2044 if (kind == kAccessor) {
2045 ExtractAccessorPairProperty(parent_obj, parent_entry, reference_name, 2045 ExtractAccessorPairProperty(parent_obj, parent_entry, reference_name,
2046 child_obj, field_offset); 2046 child_obj, field_offset);
(...skipping 20 matching lines...) Expand all
2067 ? names_->GetFormatted( 2067 ? names_->GetFormatted(
2068 name_format_string, 2068 name_format_string,
2069 String::cast(reference_name)->ToCString( 2069 String::cast(reference_name)->ToCString(
2070 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).get()) : 2070 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).get()) :
2071 names_->GetName(reference_name); 2071 names_->GetName(reference_name);
2072 2072
2073 filler_->SetNamedReference(type, 2073 filler_->SetNamedReference(type,
2074 parent_entry, 2074 parent_entry,
2075 name, 2075 name,
2076 child_entry); 2076 child_entry);
2077 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2077 MarkVisitedField(parent_obj, field_offset);
2078 } 2078 }
2079 } 2079 }
2080 2080
2081 2081
2082 void V8HeapExplorer::SetRootGcRootsReference() { 2082 void V8HeapExplorer::SetRootGcRootsReference() {
2083 filler_->SetIndexedAutoIndexReference( 2083 filler_->SetIndexedAutoIndexReference(
2084 HeapGraphEdge::kElement, 2084 HeapGraphEdge::kElement,
2085 snapshot_->root()->index(), 2085 snapshot_->root()->index(),
2086 snapshot_->gc_roots()); 2086 snapshot_->gc_roots());
2087 } 2087 }
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 for (int i = 1; i < sorted_strings.length(); ++i) { 3171 for (int i = 1; i < sorted_strings.length(); ++i) {
3172 writer_->AddCharacter(','); 3172 writer_->AddCharacter(',');
3173 SerializeString(sorted_strings[i]); 3173 SerializeString(sorted_strings[i]);
3174 if (writer_->aborted()) return; 3174 if (writer_->aborted()) return;
3175 } 3175 }
3176 } 3176 }
3177 3177
3178 3178
3179 } // namespace internal 3179 } // namespace internal
3180 } // namespace v8 3180 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/heap-snapshot-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698