OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 js_objects_info_tree_.ForEach(this); | 326 js_objects_info_tree_.ForEach(this); |
327 } | 327 } |
328 | 328 |
329 | 329 |
330 void JSObjectsCluster::Print(StringStream* accumulator) const { | 330 void JSObjectsCluster::Print(StringStream* accumulator) const { |
331 ASSERT(!is_null()); | 331 ASSERT(!is_null()); |
332 if (constructor_ == FromSpecialCase(ROOTS)) { | 332 if (constructor_ == FromSpecialCase(ROOTS)) { |
333 accumulator->Add("(roots)"); | 333 accumulator->Add("(roots)"); |
334 } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) { | 334 } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) { |
335 accumulator->Add("(global property)"); | 335 accumulator->Add("(global property)"); |
| 336 } else if (constructor_ == FromSpecialCase(SELF)) { |
| 337 accumulator->Add("(self)"); |
336 } else { | 338 } else { |
337 SmartPointer<char> s_name( | 339 SmartPointer<char> s_name( |
338 constructor_->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); | 340 constructor_->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); |
339 accumulator->Add("%s", (*s_name)[0] != '\0' ? *s_name : "(anonymous)"); | 341 accumulator->Add("%s", (*s_name)[0] != '\0' ? *s_name : "(anonymous)"); |
340 if (instance_ != NULL) { | 342 if (instance_ != NULL) { |
341 accumulator->Add(":%p", static_cast<void*>(instance_)); | 343 accumulator->Add(":%p", static_cast<void*>(instance_)); |
342 } | 344 } |
343 } | 345 } |
344 } | 346 } |
345 | 347 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 if (a.refs.length() > b.refs.length()) return 1; | 388 if (a.refs.length() > b.refs.length()) return 1; |
387 for (int i = 0; i < a.refs.length(); ++i) { | 389 for (int i = 0; i < a.refs.length(); ++i) { |
388 int cmp = JSObjectsCluster::Compare(a.refs[i], b.refs[i]); | 390 int cmp = JSObjectsCluster::Compare(a.refs[i], b.refs[i]); |
389 if (cmp != 0) return cmp; | 391 if (cmp != 0) return cmp; |
390 } | 392 } |
391 return 0; | 393 return 0; |
392 } | 394 } |
393 | 395 |
394 | 396 |
395 ClustersCoarser::ClustersCoarser() | 397 ClustersCoarser::ClustersCoarser() |
396 : zscope_(DELETE_ON_EXIT), | 398 : zscope_(DELETE_ON_EXIT), |
397 sim_list_(ClustersCoarser::kInitialSimilarityListCapacity), | 399 sim_list_(ClustersCoarser::kInitialSimilarityListCapacity), |
398 current_pair_(NULL) { | 400 current_pair_(NULL), |
| 401 current_set_(NULL), |
| 402 self_(NULL) { |
399 } | 403 } |
400 | 404 |
401 | 405 |
402 void ClustersCoarser::Call(const JSObjectsCluster& cluster, | 406 void ClustersCoarser::Call(const JSObjectsCluster& cluster, |
403 JSObjectsClusterTree* tree) { | 407 JSObjectsClusterTree* tree) { |
404 if (!cluster.can_be_coarsed()) return; | 408 if (!cluster.can_be_coarsed()) return; |
405 ClusterBackRefs pair(cluster); | 409 ClusterBackRefs pair(cluster); |
406 ASSERT(current_pair_ == NULL); | 410 ASSERT(current_pair_ == NULL); |
407 current_pair_ = &pair; | 411 current_pair_ = &pair; |
408 current_set_ = new JSObjectsRetainerTree(); | 412 current_set_ = new JSObjectsRetainerTree(); |
| 413 self_ = &cluster; |
409 tree->ForEach(this); | 414 tree->ForEach(this); |
410 sim_list_.Add(pair); | 415 sim_list_.Add(pair); |
411 current_pair_ = NULL; | 416 current_pair_ = NULL; |
412 current_set_ = NULL; | 417 current_set_ = NULL; |
| 418 self_ = NULL; |
413 } | 419 } |
414 | 420 |
415 | 421 |
416 void ClustersCoarser::Call(const JSObjectsCluster& cluster, | 422 void ClustersCoarser::Call(const JSObjectsCluster& cluster, |
417 const NumberAndSizeInfo& number_and_size) { | 423 const NumberAndSizeInfo& number_and_size) { |
418 ASSERT(current_pair_ != NULL); | 424 ASSERT(current_pair_ != NULL); |
419 ASSERT(current_set_ != NULL); | 425 ASSERT(current_set_ != NULL); |
| 426 ASSERT(self_ != NULL); |
| 427 JSObjectsRetainerTree::Locator loc; |
| 428 if (JSObjectsCluster::Compare(*self_, cluster) == 0) { |
| 429 current_pair_->refs.Add(JSObjectsCluster(JSObjectsCluster::SELF)); |
| 430 return; |
| 431 } |
420 JSObjectsCluster eq = GetCoarseEquivalent(cluster); | 432 JSObjectsCluster eq = GetCoarseEquivalent(cluster); |
421 JSObjectsRetainerTree::Locator loc; | |
422 if (!eq.is_null()) { | 433 if (!eq.is_null()) { |
423 if (current_set_->Find(eq, &loc)) return; | 434 if (current_set_->Find(eq, &loc)) return; |
424 current_pair_->refs.Add(eq); | 435 current_pair_->refs.Add(eq); |
425 current_set_->Insert(eq, &loc); | 436 current_set_->Insert(eq, &loc); |
426 } else { | 437 } else { |
427 current_pair_->refs.Add(cluster); | 438 current_pair_->refs.Add(cluster); |
428 } | 439 } |
429 } | 440 } |
430 | 441 |
431 | 442 |
432 void ClustersCoarser::Process(JSObjectsRetainerTree* tree) { | 443 void ClustersCoarser::Process(JSObjectsRetainerTree* tree) { |
433 int last_eq_clusters = -1; | 444 int last_eq_clusters = -1; |
434 for (int i = 0; i < kMaxPassesCount; ++i) { | 445 for (int i = 0; i < kMaxPassesCount; ++i) { |
435 sim_list_.Clear(); | 446 sim_list_.Clear(); |
436 const int curr_eq_clusters = DoProcess(tree); | 447 const int curr_eq_clusters = DoProcess(tree); |
437 // If no new cluster equivalents discovered, abort processing. | 448 // If no new cluster equivalents discovered, abort processing. |
438 if (last_eq_clusters == curr_eq_clusters) break; | 449 if (last_eq_clusters == curr_eq_clusters) break; |
439 last_eq_clusters = curr_eq_clusters; | 450 last_eq_clusters = curr_eq_clusters; |
440 } | 451 } |
441 } | 452 } |
442 | 453 |
443 | 454 |
444 int ClustersCoarser::DoProcess(JSObjectsRetainerTree* tree) { | 455 int ClustersCoarser::DoProcess(JSObjectsRetainerTree* tree) { |
445 tree->ForEach(this); | 456 tree->ForEach(this); |
446 // To sort similarity list properly, references list of a cluster is | 457 sim_list_.Iterate(ClusterBackRefs::SortRefsIterator); |
447 // required to be sorted, thus 'O1 <- A, B' and 'O2 <- B, A' would | |
448 // be considered equivalent. But we don't sort them explicitly | |
449 // because we know that they come from a splay tree traversal, so | |
450 // they are already sorted. | |
451 sim_list_.Sort(ClusterBackRefsCmp); | 458 sim_list_.Sort(ClusterBackRefsCmp); |
452 return FillEqualityTree(); | 459 return FillEqualityTree(); |
453 } | 460 } |
454 | 461 |
455 | 462 |
456 JSObjectsCluster ClustersCoarser::GetCoarseEquivalent( | 463 JSObjectsCluster ClustersCoarser::GetCoarseEquivalent( |
457 const JSObjectsCluster& cluster) { | 464 const JSObjectsCluster& cluster) { |
458 if (!cluster.can_be_coarsed()) return JSObjectsCluster(); | 465 if (!cluster.can_be_coarsed()) return JSObjectsCluster(); |
459 EqualityTree::Locator loc; | 466 EqualityTree::Locator loc; |
460 return eq_tree_.Find(cluster, &loc) ? loc.value() : JSObjectsCluster(); | 467 return eq_tree_.Find(cluster, &loc) ? loc.value() : JSObjectsCluster(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 js_retainer_profile.PrintStats(); | 617 js_retainer_profile.PrintStats(); |
611 | 618 |
612 LOG(HeapSampleEndEvent("Heap", "allocated")); | 619 LOG(HeapSampleEndEvent("Heap", "allocated")); |
613 } | 620 } |
614 | 621 |
615 | 622 |
616 #endif // ENABLE_LOGGING_AND_PROFILING | 623 #endif // ENABLE_LOGGING_AND_PROFILING |
617 | 624 |
618 | 625 |
619 } } // namespace v8::internal | 626 } } // namespace v8::internal |
OLD | NEW |