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

Side by Side Diff: chrome/browser/fragmentation_checker_win.cc

Issue 8085026: Add a metric to Chrome to measure fragmentation of chrome.dll at startup.BUG=98033TEST=None (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/fragmentation_checker_win.h"
6
7 #include <windows.h>
8 #include <winioctl.h>
9
10 #include "base/at_exit.h"
11 #include "base/basictypes.h"
12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/logging.h"
15 #include "base/metrics/histogram.h"
16 #include "base/path_service.h"
17
18 namespace {
19
20 size_t kMaxBufferSize = 1 << 20;
grt (UTC plus 2) 2011/09/30 18:44:14 const size_t...
robertshield 2011/09/30 19:53:00 Done.
21
22 struct FileExtentData {
23 int number_of_extents;
24 int64 virtual_cluster_span;
25 };
26
27 size_t ComputeRetrievalPointersBufferSize(int number_of_extents) {
28 return sizeof(RETRIEVAL_POINTERS_BUFFER) +
29 (number_of_extents - 1) * (sizeof(LARGE_INTEGER) * 2);
grt (UTC plus 2) 2011/09/30 18:44:14 indentation
grt (UTC plus 2) 2011/09/30 18:44:14 is it possible to replace sizeof(LARGE_INTEGER) *
robertshield 2011/09/30 19:53:00 Done.
robertshield 2011/09/30 19:53:00 Done.
30 }
31
32 bool DumpFileExtents(const FilePath& file_path,
33 FileExtentData* file_extent_data) {
34 DCHECK(file_extent_data);
35 if (!file_util::PathExists(file_path)) {
grt (UTC plus 2) 2011/09/30 18:44:14 why do this extra check? CreatePlatformFile shoul
robertshield 2011/09/30 19:53:00 Done.
36 LOG(ERROR) << "File not found.";
37 return false;
38 }
39
40 bool success = false;
41
42 base::PlatformFileError error_code = base::PLATFORM_FILE_ERROR_FAILED;
43 bool created = false;
44 base::PlatformFile file_handle = CreatePlatformFile(
45 file_path,
46 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
47 &created,
48 &error_code);
49 if (error_code == base::PLATFORM_FILE_OK && !created) {
50 STARTING_VCN_INPUT_BUFFER starting_vcn_input_buffer = {0};
51
52 // Compute an output size capable of holding 16 extents at first. This may
53 // fail when the number of extents exceeds 16, in which case we make
54 // a bigger buffer up to kMaxBufferSize.
55 int number_of_extents = 16;
56 std::vector<BYTE> retrieval_pointers_buffer;
grt (UTC plus 2) 2011/09/30 18:44:14 uint8 rather than win-specific BYTE?
robertshield 2011/09/30 19:53:00 Done, although this file is (and can only be) Wind
57
58 size_t output_size = ComputeRetrievalPointersBufferSize(number_of_extents);
grt (UTC plus 2) 2011/09/30 18:44:14 do this computation before line 56, then change li
robertshield 2011/09/30 19:53:00 Done.
59 retrieval_pointers_buffer.resize(output_size);
60
61 DWORD bytes_returned = 0;
62
63 bool result = false;
64 do {
65 SetLastError(ERROR_SUCCESS);
grt (UTC plus 2) 2011/09/30 18:44:14 this is extremely odd. please document why this i
robertshield 2011/09/30 19:53:00 rejiggered as discussed.
66 result = DeviceIoControl(
grt (UTC plus 2) 2011/09/30 18:44:14 MSDN says that the call fails (returns 0) if the b
robertshield 2011/09/30 19:53:00 I found documentation suggesting using the GLE cod
67 file_handle,
68 FSCTL_GET_RETRIEVAL_POINTERS,
69 reinterpret_cast<void*>(&starting_vcn_input_buffer),
70 sizeof(starting_vcn_input_buffer),
71 reinterpret_cast<void*>(&retrieval_pointers_buffer[0]),
72 retrieval_pointers_buffer.size(),
73 &bytes_returned,
74 NULL) == TRUE;
grt (UTC plus 2) 2011/09/30 18:44:14 == TRUE -> != 0 MSDN says it returns zero/non-zero
robertshield 2011/09/30 19:53:00 My version of WinBase.h says it returns FALSE/TRUE
75
76 DWORD last_error = GetLastError();
grt (UTC plus 2) 2011/09/30 18:44:14 this is extremely odd. according to MSDN, you wou
robertshield 2011/09/30 19:53:00 Changed as discussed.
77 if (last_error == ERROR_MORE_DATA) {
78 // Grow the extents we can handle
79 number_of_extents *= 2;
80 output_size = ComputeRetrievalPointersBufferSize(number_of_extents);
81
82 if (output_size > kMaxBufferSize) {
83 LOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS output buffer exceeded "
84 "maximum size.";
85 result = false;
86 break;
87 }
88
89 retrieval_pointers_buffer.clear();
90 retrieval_pointers_buffer.resize(output_size);
grt (UTC plus 2) 2011/09/30 18:44:14 replace these two lines with a call to .assign(out
robertshield 2011/09/30 19:53:00 Done.
91 } else {
92 if (!result) {
93 LOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS failed. gle = "
grt (UTC plus 2) 2011/09/30 18:44:14 PLOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS faile
robertshield 2011/09/30 19:53:00 Done.
94 << last_error;
95 }
96 break;
97 }
98 } while (true);
99
100 if (result) {
101 RETRIEVAL_POINTERS_BUFFER* retrieval_pointers =
102 reinterpret_cast<RETRIEVAL_POINTERS_BUFFER*>(
103 &retrieval_pointers_buffer[0]);
104 DWORD extent_count = retrieval_pointers->ExtentCount;
105 LARGE_INTEGER extent_cluster_range = {0};
106 if (extent_count > 0) {
107 extent_cluster_range.QuadPart =
108 retrieval_pointers->Extents[extent_count - 1].NextVcn.QuadPart;
109 extent_cluster_range.QuadPart -=
110 retrieval_pointers->StartingVcn.QuadPart;
111 }
112
113 file_extent_data->number_of_extents = extent_count;
grt (UTC plus 2) 2011/09/30 18:44:14 this does (in essence) a uint32 -> int conversion.
robertshield 2011/09/30 19:53:00 Done.
114 file_extent_data->virtual_cluster_span = extent_cluster_range.QuadPart;
115 success = true;
116 } else {
117 LOG(ERROR) << "Failed to retrieve extents.";
118 }
119 }
120
121 return success;
122 }
123
124 } // namespace
125
126 namespace fragmentation_checker {
127
128 void RecordFragmentationMetricForCurrentModule() {
129 FilePath module_path;
grt (UTC plus 2) 2011/09/30 18:44:14 #include "base/file_path.h" for this
robertshield 2011/09/30 19:53:00 Done.
130 if (PathService::Get(base::FILE_MODULE, &module_path)) {
131 FileExtentData file_extent_data = {0};
132 if (DumpFileExtents(module_path, &file_extent_data)) {
133 UMA_HISTOGRAM_COUNTS("Fragmentation.ModuleExtents",
134 file_extent_data.number_of_extents);
135 UMA_HISTOGRAM_COUNTS("Fragmentation.ModuleSpan",
136 file_extent_data.virtual_cluster_span);
grt (UTC plus 2) 2011/09/30 18:44:14 1) this macro sets the max sample to 1000000, whic
robertshield 2011/09/30 19:53:00 As discussed, while reading the documentation agai
137 }
138 } else {
139 NOTREACHED() << "Could not get path to current module.";
140 }
141 }
142
143 } // namespace fragmentation_checker
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698