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

Side by Side Diff: components/tracing/common/process_metrics_memory_dump_provider.cc

Issue 2826123004: Use faster, but less information methods to calculate memory dumps on macOS. (Closed)
Patch Set: fix ios compile error. Created 3 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium 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 "components/tracing/common/process_metrics_memory_dump_provider.h" 5 #include "components/tracing/common/process_metrics_memory_dump_provider.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
(...skipping 18 matching lines...) Expand all
29 #include <mach/mach.h> 29 #include <mach/mach.h>
30 #include <mach/mach_vm.h> 30 #include <mach/mach_vm.h>
31 #include <mach/shared_region.h> 31 #include <mach/shared_region.h>
32 #include <sys/param.h> 32 #include <sys/param.h>
33 33
34 #include <mach-o/dyld_images.h> 34 #include <mach-o/dyld_images.h>
35 #include <mach-o/loader.h> 35 #include <mach-o/loader.h>
36 #include <mach/mach.h> 36 #include <mach/mach.h>
37 37
38 #include "base/numerics/safe_math.h" 38 #include "base/numerics/safe_math.h"
39 #include "base/process/process_metrics.h"
39 #endif // defined(OS_MACOSX) 40 #endif // defined(OS_MACOSX)
40 41
41 #if defined(OS_WIN) 42 #if defined(OS_WIN)
42 #include <psapi.h> 43 #include <psapi.h>
43 #include <tchar.h> 44 #include <tchar.h>
44 #include <windows.h> 45 #include <windows.h>
45 46
46 #include <base/strings/sys_string_conversions.h> 47 #include <base/strings/sys_string_conversions.h>
47 #include <base/win/win_util.h> 48 #include <base/win/win_util.h>
48 #endif // defined(OS_WIN) 49 #endif // defined(OS_WIN)
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 381
381 // We intentionally avoid setting any page information, which is not 382 // We intentionally avoid setting any page information, which is not
382 // available from dyld. The fields will be populated later. 383 // available from dyld. The fields will be populated later.
383 regions->push_back(region); 384 regions->push_back(region);
384 } 385 }
385 } 386 }
386 } 387 }
387 return true; 388 return true;
388 } 389 }
389 390
390 void PopulateByteStats(VMRegion* region, const vm_region_submap_info_64& info) { 391 void PopulateByteStats(VMRegion* region,
391 uint32_t share_mode = info.share_mode; 392 const vm_region_top_info_data_t& info) {
392 if (share_mode == SM_COW && info.ref_count == 1) 393 uint64_t dirty_bytes =
393 share_mode = SM_PRIVATE; 394 (info.private_pages_resident + info.shared_pages_resident) * PAGE_SIZE;
394 395 switch (info.share_mode) {
395 uint64_t dirty_bytes = info.pages_dirtied * PAGE_SIZE;
396 uint64_t clean_bytes =
397 (info.pages_resident - info.pages_reusable - info.pages_dirtied) *
398 PAGE_SIZE;
399 switch (share_mode) {
400 case SM_LARGE_PAGE: 396 case SM_LARGE_PAGE:
401 case SM_PRIVATE: 397 case SM_PRIVATE:
402 region->byte_stats_private_dirty_resident = dirty_bytes;
403 region->byte_stats_private_clean_resident = clean_bytes;
404 break;
405 case SM_COW: 398 case SM_COW:
406 region->byte_stats_private_dirty_resident = dirty_bytes; 399 region->byte_stats_private_dirty_resident = dirty_bytes;
407 region->byte_stats_shared_clean_resident = clean_bytes;
408 break;
409 case SM_SHARED: 400 case SM_SHARED:
410 case SM_PRIVATE_ALIASED: 401 case SM_PRIVATE_ALIASED:
411 case SM_TRUESHARED: 402 case SM_TRUESHARED:
412 case SM_SHARED_ALIASED: 403 case SM_SHARED_ALIASED:
413 region->byte_stats_shared_dirty_resident = dirty_bytes; 404 region->byte_stats_shared_dirty_resident = dirty_bytes;
414 region->byte_stats_shared_clean_resident = clean_bytes;
415 break; 405 break;
416 case SM_EMPTY: 406 case SM_EMPTY:
417 break; 407 break;
418 default: 408 default:
419 NOTREACHED(); 409 NOTREACHED();
420 break; 410 break;
421 } 411 }
422 } 412 }
423 413
424 // Creates VMRegions from mach_vm_region_recurse. Returns whether the operation 414 // Creates VMRegions using mach vm syscalls. Returns whether the operation
425 // succeeded. 415 // succeeded.
426 bool GetAllRegions(std::vector<VMRegion>* regions) { 416 bool GetAllRegions(std::vector<VMRegion>* regions) {
427 const int pid = getpid(); 417 const int pid = getpid();
428 task_t task = mach_task_self(); 418 task_t task = mach_task_self();
429 mach_vm_size_t size = 0; 419 mach_vm_size_t size = 0;
430 vm_region_submap_info_64 info;
431 natural_t depth = 1;
432 mach_msg_type_number_t count = sizeof(info);
433 mach_vm_address_t address = MACH_VM_MIN_ADDRESS; 420 mach_vm_address_t address = MACH_VM_MIN_ADDRESS;
434 while (true) { 421 while (true) {
435 memset(&info, 0, sizeof(info)); 422 base::CheckedNumeric<mach_vm_address_t> numeric(address);
Mark Mentovai 2017/04/21 12:33:52 “numeric” again
erikchen 2017/04/21 18:20:25 Done.
436 kern_return_t kr = mach_vm_region_recurse( 423 numeric += size;
437 task, &address, &size, &depth, 424 if (!numeric.IsValid())
438 reinterpret_cast<vm_region_info_t>(&info), &count); 425 return false;
439 if (kr == KERN_INVALID_ADDRESS) // nothing else left 426 address = numeric.ValueOrDie();
427 mach_vm_address_t address_copy = address;
428
429 vm_region_top_info_data_t info;
430 base::MachVMRegionResult result =
431 base::GetTopInfo(task, &size, &address, &info);
432 if (result == base::MachVMRegionResult::Error)
433 return false;
434 if (result == base::MachVMRegionResult::Finished)
440 break; 435 break;
441 if (kr != KERN_SUCCESS) // something bad 436
437 vm_region_basic_info_64 basic_info;
438 mach_vm_size_t dummy_size = 0;
439 result = base::GetBasicInfo(task, &dummy_size, &address_copy, &basic_info);
440 if (result == base::MachVMRegionResult::Error)
442 return false; 441 return false;
443 if (info.is_submap) { 442 if (result == base::MachVMRegionResult::Finished)
444 size = 0; 443 break;
445 ++depth;
446 continue;
447 }
448 444
449 VMRegion region; 445 VMRegion region;
450 PopulateByteStats(&region, info); 446 PopulateByteStats(&region, info);
451 447
452 if (info.protection & VM_PROT_READ) 448 if (basic_info.protection & VM_PROT_READ)
453 region.protection_flags |= VMRegion::kProtectionFlagsRead; 449 region.protection_flags |= VMRegion::kProtectionFlagsRead;
454 if (info.protection & VM_PROT_WRITE) 450 if (basic_info.protection & VM_PROT_WRITE)
455 region.protection_flags |= VMRegion::kProtectionFlagsWrite; 451 region.protection_flags |= VMRegion::kProtectionFlagsWrite;
456 if (info.protection & VM_PROT_EXECUTE) 452 if (basic_info.protection & VM_PROT_EXECUTE)
457 region.protection_flags |= VMRegion::kProtectionFlagsExec; 453 region.protection_flags |= VMRegion::kProtectionFlagsExec;
458 454
459 char buffer[MAXPATHLEN]; 455 char buffer[MAXPATHLEN];
460 int length = proc_regionfilename(pid, address, buffer, MAXPATHLEN); 456 int length = proc_regionfilename(pid, address, buffer, MAXPATHLEN);
461 if (length != 0) 457 if (length != 0)
462 region.mapped_file.assign(buffer, length); 458 region.mapped_file.assign(buffer, length);
463 459
464 region.byte_stats_swapped = info.pages_swapped_out * PAGE_SIZE; 460 // There's no way to get swapped bytes without doing a very-expensive
461 // syscalls that craws every single page in the memory object. Set as 0
Primiano Tucci (use gerrit) 2017/04/21 11:36:31 I guess you intended s/craws/crawls/ ?
erikchen 2017/04/21 18:20:25 Done.
462 // here, but know that it's inaccurate.
463 region.byte_stats_swapped = 0;
Primiano Tucci (use gerrit) 2017/04/21 11:36:31 This one seems not too useful, as VMRegion is zero
erikchen 2017/04/21 18:20:25 Done.
465 region.start_address = address; 464 region.start_address = address;
466 region.size_in_bytes = size; 465 region.size_in_bytes = size;
467 regions->push_back(region); 466 regions->push_back(region);
468
469 base::CheckedNumeric<mach_vm_address_t> numeric(address);
470 numeric += size;
471 if (!numeric.IsValid())
472 return false;
473 address = numeric.ValueOrDie();
474 } 467 }
475 return true; 468 return true;
476 } 469 }
477 470
478 void AddRegionByteStats(VMRegion* dest, const VMRegion& source) { 471 void AddRegionByteStats(VMRegion* dest, const VMRegion& source) {
479 dest->byte_stats_private_dirty_resident += 472 dest->byte_stats_private_dirty_resident +=
480 source.byte_stats_private_dirty_resident; 473 source.byte_stats_private_dirty_resident;
481 dest->byte_stats_private_clean_resident += 474 dest->byte_stats_private_clean_resident +=
482 source.byte_stats_private_clean_resident; 475 source.byte_stats_private_clean_resident;
483 dest->byte_stats_shared_dirty_resident += 476 dest->byte_stats_shared_dirty_resident +=
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 #endif 700 #endif
708 } 701 }
709 702
710 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() { 703 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() {
711 #if defined(OS_LINUX) || defined(OS_ANDROID) 704 #if defined(OS_LINUX) || defined(OS_ANDROID)
712 fast_polling_statm_fd_.reset(); 705 fast_polling_statm_fd_.reset();
713 #endif 706 #endif
714 } 707 }
715 708
716 } // namespace tracing 709 } // namespace tracing
OLDNEW
« base/process/process_metrics_mac.cc ('K') | « base/process/process_metrics_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698