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

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

Issue 10025014: Revert "External references should not affect dominance relation." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 8 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
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 index_ = index; 950 index_ = index;
951 to_ = to; 951 to_ = to;
952 } 952 }
953 953
954 954
955 void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) { 955 void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) {
956 Init(child_index, kElement, index, to); 956 Init(child_index, kElement, index, to);
957 } 957 }
958 958
959 959
960 HeapEntry* HeapGraphEdge::From() {
961 return reinterpret_cast<HeapEntry*>(this - child_index_) - 1;
962 }
963
964
960 void HeapEntry::Init(HeapSnapshot* snapshot, 965 void HeapEntry::Init(HeapSnapshot* snapshot,
961 Type type, 966 Type type,
962 const char* name, 967 const char* name,
963 SnapshotObjectId id, 968 SnapshotObjectId id,
964 int self_size, 969 int self_size,
965 int children_count, 970 int children_count,
966 int retainers_count) { 971 int retainers_count) {
967 snapshot_ = snapshot; 972 snapshot_ = snapshot;
968 type_ = type; 973 type_ = type;
969 painted_ = false; 974 painted_ = false;
970 reachable_from_window_ = false;
971 name_ = name; 975 name_ = name;
972 self_size_ = self_size; 976 self_size_ = self_size;
973 retained_size_ = 0; 977 retained_size_ = 0;
974 entry_index_ = -1; 978 entry_index_ = -1;
975 children_count_ = children_count; 979 children_count_ = children_count;
976 retainers_count_ = retainers_count; 980 retainers_count_ = retainers_count;
977 dominator_ = NULL; 981 dominator_ = NULL;
978 id_ = id; 982 id_ = id;
979 } 983 }
980 984
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 break; 2171 break;
2168 } 2172 }
2169 } 2173 }
2170 } else { 2174 } else {
2171 StringDictionary* dictionary = js_obj->property_dictionary(); 2175 StringDictionary* dictionary = js_obj->property_dictionary();
2172 int length = dictionary->Capacity(); 2176 int length = dictionary->Capacity();
2173 for (int i = 0; i < length; ++i) { 2177 for (int i = 0; i < length; ++i) {
2174 Object* k = dictionary->KeyAt(i); 2178 Object* k = dictionary->KeyAt(i);
2175 if (dictionary->IsKey(k)) { 2179 if (dictionary->IsKey(k)) {
2176 Object* target = dictionary->ValueAt(i); 2180 Object* target = dictionary->ValueAt(i);
2181 SetPropertyReference(
2182 js_obj, entry, String::cast(k), target);
2177 // We assume that global objects can only have slow properties. 2183 // We assume that global objects can only have slow properties.
2178 Object* value = target->IsJSGlobalPropertyCell() 2184 if (target->IsJSGlobalPropertyCell()) {
2179 ? JSGlobalPropertyCell::cast(target)->value() 2185 SetPropertyShortcutReference(js_obj,
2180 : target; 2186 entry,
2181 if (String::cast(k)->length() > 0) { 2187 String::cast(k),
2182 SetPropertyReference(js_obj, entry, String::cast(k), value); 2188 JSGlobalPropertyCell::cast(
2183 } else { 2189 target)->value());
2184 TagObject(value, "(hidden properties)");
2185 SetInternalReference(js_obj, entry, "hidden_properties", value);
2186 } 2190 }
2187 } 2191 }
2188 } 2192 }
2189 } 2193 }
2190 } 2194 }
2191 2195
2192 2196
2193 void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, 2197 void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
2194 HeapEntry* entry) { 2198 HeapEntry* entry) {
2195 if (js_obj->HasFastElements()) { 2199 if (js_obj->HasFastElements()) {
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 isolate->factory()->NewStringFromAscii(CStrVector("document")); 2630 isolate->factory()->NewStringFromAscii(CStrVector("document"));
2627 Handle<String> url_string = 2631 Handle<String> url_string =
2628 isolate->factory()->NewStringFromAscii(CStrVector("URL")); 2632 isolate->factory()->NewStringFromAscii(CStrVector("URL"));
2629 const char** urls = NewArray<const char*>(enumerator.count()); 2633 const char** urls = NewArray<const char*>(enumerator.count());
2630 for (int i = 0, l = enumerator.count(); i < l; ++i) { 2634 for (int i = 0, l = enumerator.count(); i < l; ++i) {
2631 urls[i] = NULL; 2635 urls[i] = NULL;
2632 HandleScope scope; 2636 HandleScope scope;
2633 Handle<JSGlobalObject> global_obj = enumerator.at(i); 2637 Handle<JSGlobalObject> global_obj = enumerator.at(i);
2634 Object* obj_document; 2638 Object* obj_document;
2635 if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) && 2639 if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) &&
2636 obj_document->IsJSObject()) { 2640 obj_document->IsJSObject()) {
2637 JSObject* document = JSObject::cast(obj_document); 2641 JSObject* document = JSObject::cast(obj_document);
2638 Object* obj_url; 2642 Object* obj_url;
2639 if (document->GetProperty(*url_string)->ToObject(&obj_url) && 2643 if (document->GetProperty(*url_string)->ToObject(&obj_url) &&
2640 obj_url->IsString()) { 2644 obj_url->IsString()) {
2641 urls[i] = collection_->names()->GetName(String::cast(obj_url)); 2645 urls[i] = collection_->names()->GetName(String::cast(obj_url));
2642 } 2646 }
2643 } 2647 }
2644 } 2648 }
2645 2649
2646 AssertNoAllocation no_allocation; 2650 AssertNoAllocation no_allocation;
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
3180 // in turn may relocate objects in property maps thus changing the heap 3184 // in turn may relocate objects in property maps thus changing the heap
3181 // layout and affecting retainer counts. This is not acceptable because 3185 // layout and affecting retainer counts. This is not acceptable because
3182 // number of retainers must not change between count and fill passes. 3186 // number of retainers must not change between count and fill passes.
3183 // To avoid this there's a separate postpass that set object names. 3187 // To avoid this there's a separate postpass that set object names.
3184 return v8_heap_explorer_.IterateAndExtractReferences(&filler) 3188 return v8_heap_explorer_.IterateAndExtractReferences(&filler)
3185 && dom_explorer_.IterateAndExtractReferences(&filler) 3189 && dom_explorer_.IterateAndExtractReferences(&filler)
3186 && v8_heap_explorer_.IterateAndSetObjectNames(&filler); 3190 && v8_heap_explorer_.IterateAndSetObjectNames(&filler);
3187 } 3191 }
3188 3192
3189 3193
3190 void HeapSnapshotGenerator::MarkWindowReachableObjects() { 3194 void HeapSnapshotGenerator::FillReversePostorderIndexes(
3191 List<HeapEntry*> worklist;
3192
3193 Vector<HeapGraphEdge> children = snapshot_->root()->children();
3194 for (int i = 0; i < children.length(); ++i) {
3195 if (children[i].type() == HeapGraphEdge::kShortcut) {
3196 worklist.Add(children[i].to());
3197 }
3198 }
3199
3200 while (!worklist.is_empty()) {
3201 HeapEntry* entry = worklist.RemoveLast();
3202 if (entry->reachable_from_window()) continue;
3203 entry->set_reachable_from_window();
3204 Vector<HeapGraphEdge> children = entry->children();
3205 for (int i = 0; i < children.length(); ++i) {
3206 HeapEntry* child = children[i].to();
3207 if (!child->reachable_from_window()) {
3208 worklist.Add(child);
3209 }
3210 }
3211 }
3212 }
3213
3214
3215 static bool IsRetainingEdge(HeapGraphEdge* edge) {
3216 if (edge->type() == HeapGraphEdge::kShortcut) return false;
3217 // The edge is not retaining if it goes from system domain
3218 // (i.e. an object not reachable from window) to the user domain
3219 // (i.e. a reachable object).
3220 return edge->from()->reachable_from_window()
3221 || !edge->to()->reachable_from_window();
3222 }
3223
3224
3225 void HeapSnapshotGenerator::FillPostorderIndexes(
3226 Vector<HeapEntry*>* entries) { 3195 Vector<HeapEntry*>* entries) {
3227 snapshot_->ClearPaint(); 3196 snapshot_->ClearPaint();
3228 int current_entry = 0; 3197 int current_entry = 0;
3229 List<HeapEntry*> nodes_to_visit; 3198 List<HeapEntry*> nodes_to_visit;
3230 HeapEntry* root = snapshot_->root(); 3199 nodes_to_visit.Add(snapshot_->root());
3231 nodes_to_visit.Add(root);
3232 snapshot_->root()->paint(); 3200 snapshot_->root()->paint();
3233 while (!nodes_to_visit.is_empty()) { 3201 while (!nodes_to_visit.is_empty()) {
3234 HeapEntry* entry = nodes_to_visit.last(); 3202 HeapEntry* entry = nodes_to_visit.last();
3235 Vector<HeapGraphEdge> children = entry->children(); 3203 Vector<HeapGraphEdge> children = entry->children();
3236 bool has_new_edges = false; 3204 bool has_new_edges = false;
3237 for (int i = 0; i < children.length(); ++i) { 3205 for (int i = 0; i < children.length(); ++i) {
3238 if (entry != root && !IsRetainingEdge(&children[i])) continue; 3206 if (children[i].type() == HeapGraphEdge::kShortcut) continue;
3239 HeapEntry* child = children[i].to(); 3207 HeapEntry* child = children[i].to();
3240 if (!child->painted()) { 3208 if (!child->painted()) {
3241 nodes_to_visit.Add(child); 3209 nodes_to_visit.Add(child);
3242 child->paint(); 3210 child->paint();
3243 has_new_edges = true; 3211 has_new_edges = true;
3244 } 3212 }
3245 } 3213 }
3246 if (!has_new_edges) { 3214 if (!has_new_edges) {
3247 entry->set_ordered_index(current_entry); 3215 entry->set_ordered_index(current_entry);
3248 (*entries)[current_entry++] = entry; 3216 (*entries)[current_entry++] = entry;
(...skipping 14 matching lines...) Expand all
3263 } 3231 }
3264 3232
3265 3233
3266 // The algorithm is based on the article: 3234 // The algorithm is based on the article:
3267 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm" 3235 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
3268 // Softw. Pract. Exper. 4 (2001), pp. 1-10. 3236 // Softw. Pract. Exper. 4 (2001), pp. 1-10.
3269 bool HeapSnapshotGenerator::BuildDominatorTree( 3237 bool HeapSnapshotGenerator::BuildDominatorTree(
3270 const Vector<HeapEntry*>& entries, 3238 const Vector<HeapEntry*>& entries,
3271 Vector<int>* dominators) { 3239 Vector<int>* dominators) {
3272 if (entries.length() == 0) return true; 3240 if (entries.length() == 0) return true;
3273 HeapEntry* root = snapshot_->root();
3274 const int entries_length = entries.length(), root_index = entries_length - 1; 3241 const int entries_length = entries.length(), root_index = entries_length - 1;
3275 static const int kNoDominator = -1; 3242 static const int kNoDominator = -1;
3276 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; 3243 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator;
3277 (*dominators)[root_index] = root_index; 3244 (*dominators)[root_index] = root_index;
3278 3245
3279 // The affected array is used to mark entries which dominators 3246 // The affected array is used to mark entries which dominators
3280 // have to be racalculated because of changes in their retainers. 3247 // have to be racalculated because of changes in their retainers.
3281 ScopedVector<bool> affected(entries_length); 3248 ScopedVector<bool> affected(entries_length);
3282 for (int i = 0; i < affected.length(); ++i) affected[i] = false; 3249 for (int i = 0; i < affected.length(); ++i) affected[i] = false;
3283 // Mark the root direct children as affected. 3250 // Mark the root direct children as affected.
3284 Vector<HeapGraphEdge> children = entries[root_index]->children(); 3251 Vector<HeapGraphEdge> children = entries[root_index]->children();
3285 for (int i = 0; i < children.length(); ++i) { 3252 for (int i = 0; i < children.length(); ++i) {
3286 affected[children[i].to()->ordered_index()] = true; 3253 affected[children[i].to()->ordered_index()] = true;
3287 } 3254 }
3288 3255
3289 bool changed = true; 3256 bool changed = true;
3290 while (changed) { 3257 while (changed) {
3291 changed = false; 3258 changed = false;
3292 if (!ProgressReport(true)) return false; 3259 if (!ProgressReport(true)) return false;
3293 for (int i = root_index - 1; i >= 0; --i) { 3260 for (int i = root_index - 1; i >= 0; --i) {
3294 if (!affected[i]) continue; 3261 if (!affected[i]) continue;
3295 affected[i] = false; 3262 affected[i] = false;
3296 // If dominator of the entry has already been set to root, 3263 // If dominator of the entry has already been set to root,
3297 // then it can't propagate any further. 3264 // then it can't propagate any further.
3298 if ((*dominators)[i] == root_index) continue; 3265 if ((*dominators)[i] == root_index) continue;
3299 int new_idom_index = kNoDominator; 3266 int new_idom_index = kNoDominator;
3300 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); 3267 Vector<HeapGraphEdge*> rets = entries[i]->retainers();
3301 for (int j = 0; j < rets.length(); ++j) { 3268 for (int j = 0; j < rets.length(); ++j) {
3302 if (rets[j]->from() != root && !IsRetainingEdge(rets[j])) continue; 3269 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
3303 int ret_index = rets[j]->from()->ordered_index(); 3270 int ret_index = rets[j]->From()->ordered_index();
3304 if (dominators->at(ret_index) != kNoDominator) { 3271 if (dominators->at(ret_index) != kNoDominator) {
3305 new_idom_index = new_idom_index == kNoDominator 3272 new_idom_index = new_idom_index == kNoDominator
3306 ? ret_index 3273 ? ret_index
3307 : Intersect(ret_index, new_idom_index, *dominators); 3274 : Intersect(ret_index, new_idom_index, *dominators);
3308 // If idom has already reached the root, it doesn't make sense 3275 // If idom has already reached the root, it doesn't make sense
3309 // to check other retainers. 3276 // to check other retainers.
3310 if (new_idom_index == root_index) break; 3277 if (new_idom_index == root_index) break;
3311 } 3278 }
3312 } 3279 }
3313 if (new_idom_index != kNoDominator 3280 if (new_idom_index != kNoDominator
3314 && dominators->at(i) != new_idom_index) { 3281 && dominators->at(i) != new_idom_index) {
3315 (*dominators)[i] = new_idom_index; 3282 (*dominators)[i] = new_idom_index;
3316 changed = true; 3283 changed = true;
3317 Vector<HeapGraphEdge> children = entries[i]->children(); 3284 Vector<HeapGraphEdge> children = entries[i]->children();
3318 for (int j = 0; j < children.length(); ++j) { 3285 for (int j = 0; j < children.length(); ++j) {
3319 affected[children[j].to()->ordered_index()] = true; 3286 affected[children[j].to()->ordered_index()] = true;
3320 } 3287 }
3321 } 3288 }
3322 } 3289 }
3323 } 3290 }
3324 return true; 3291 return true;
3325 } 3292 }
3326 3293
3327 3294
3328 bool HeapSnapshotGenerator::SetEntriesDominators() { 3295 bool HeapSnapshotGenerator::SetEntriesDominators() {
3329 MarkWindowReachableObjects(); 3296 // This array is used for maintaining reverse postorder of nodes.
3330 // This array is used for maintaining postorder of nodes.
3331 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); 3297 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
3332 FillPostorderIndexes(&ordered_entries); 3298 FillReversePostorderIndexes(&ordered_entries);
3333 ScopedVector<int> dominators(ordered_entries.length()); 3299 ScopedVector<int> dominators(ordered_entries.length());
3334 if (!BuildDominatorTree(ordered_entries, &dominators)) return false; 3300 if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
3335 for (int i = 0; i < ordered_entries.length(); ++i) { 3301 for (int i = 0; i < ordered_entries.length(); ++i) {
3336 ASSERT(dominators[i] >= 0); 3302 ASSERT(dominators[i] >= 0);
3337 ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]); 3303 ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]);
3338 } 3304 }
3339 return true; 3305 return true;
3340 } 3306 }
3341 3307
3342 3308
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
3790 3756
3791 3757
3792 void HeapSnapshotJSONSerializer::SortHashMap( 3758 void HeapSnapshotJSONSerializer::SortHashMap(
3793 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 3759 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
3794 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 3760 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
3795 sorted_entries->Add(p); 3761 sorted_entries->Add(p);
3796 sorted_entries->Sort(SortUsingEntryValue); 3762 sorted_entries->Sort(SortUsingEntryValue);
3797 } 3763 }
3798 3764
3799 } } // namespace v8::internal 3765 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698