| Index: chrome/browser/metrics/metrics_log.cc | 
| diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc | 
| index 58cdfa1c312eaeb8f63e7538c4ae04dbfbff9814..47071fa69a29de6f1648e701161156b78dfca0d5 100644 | 
| --- a/chrome/browser/metrics/metrics_log.cc | 
| +++ b/chrome/browser/metrics/metrics_log.cc | 
| @@ -12,11 +12,13 @@ | 
| #include "base/lazy_instance.h" | 
| #include "base/memory/scoped_ptr.h" | 
| #include "base/perftimer.h" | 
| +#include "base/profiler/alternate_timer.h" | 
| #include "base/string_number_conversions.h" | 
| #include "base/string_util.h" | 
| #include "base/sys_info.h" | 
| #include "base/third_party/nspr/prtime.h" | 
| #include "base/time.h" | 
| +#include "base/tracked_objects.h" | 
| #include "base/utf_string_conversions.h" | 
| #include "chrome/browser/autocomplete/autocomplete.h" | 
| #include "chrome/browser/autocomplete/autocomplete_match.h" | 
| @@ -27,12 +29,13 @@ | 
| #include "chrome/common/chrome_version_info.h" | 
| #include "chrome/common/logging_chrome.h" | 
| #include "chrome/common/metrics/proto/omnibox_event.pb.h" | 
| +#include "chrome/common/metrics/proto/profiler_event.pb.h" | 
| #include "chrome/common/metrics/proto/system_profile.pb.h" | 
| #include "chrome/common/pref_names.h" | 
| #include "content/public/browser/content_browser_client.h" | 
| #include "content/public/browser/gpu_data_manager.h" | 
| -#include "content/public/common/gpu_info.h" | 
| #include "content/public/common/content_client.h" | 
| +#include "content/public/common/gpu_info.h" | 
| #include "googleurl/src/gurl.h" | 
| #include "ui/gfx/screen.h" | 
| #include "webkit/plugins/webplugininfo.h" | 
| @@ -46,7 +49,9 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; | 
|  | 
| using content::GpuDataManager; | 
| using metrics::OmniboxEventProto; | 
| +using metrics::ProfilerEventProto; | 
| using metrics::SystemProfileProto; | 
| +using tracked_objects::ProcessDataSnapshot; | 
| typedef base::FieldTrial::NameGroupId NameGroupId; | 
|  | 
| namespace { | 
| @@ -141,6 +146,41 @@ OmniboxEventProto::Suggestion::ResultType AsOmniboxEventResultType( | 
| } | 
| } | 
|  | 
| +ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType( | 
| +    content::ProcessType process_type) { | 
| +  switch (process_type) { | 
| +    case content::PROCESS_TYPE_BROWSER: | 
| +      return ProfilerEventProto::TrackedObject::BROWSER; | 
| +    case content::PROCESS_TYPE_RENDERER: | 
| +      return ProfilerEventProto::TrackedObject::RENDERER; | 
| +    case content::PROCESS_TYPE_PLUGIN: | 
| +      return ProfilerEventProto::TrackedObject::PLUGIN; | 
| +    case content::PROCESS_TYPE_WORKER: | 
| +      return ProfilerEventProto::TrackedObject::WORKER; | 
| +    case content::PROCESS_TYPE_NACL_LOADER: | 
| +      return ProfilerEventProto::TrackedObject::NACL_LOADER; | 
| +    case content::PROCESS_TYPE_UTILITY: | 
| +      return ProfilerEventProto::TrackedObject::UTILITY; | 
| +    case content::PROCESS_TYPE_PROFILE_IMPORT: | 
| +      return ProfilerEventProto::TrackedObject::PROFILE_IMPORT; | 
| +    case content::PROCESS_TYPE_ZYGOTE: | 
| +      return ProfilerEventProto::TrackedObject::ZYGOTE; | 
| +    case content::PROCESS_TYPE_SANDBOX_HELPER: | 
| +      return ProfilerEventProto::TrackedObject::SANDBOX_HELPER; | 
| +    case content::PROCESS_TYPE_NACL_BROKER: | 
| +      return ProfilerEventProto::TrackedObject::NACL_BROKER; | 
| +    case content::PROCESS_TYPE_GPU: | 
| +      return ProfilerEventProto::TrackedObject::GPU; | 
| +    case content::PROCESS_TYPE_PPAPI_PLUGIN: | 
| +      return ProfilerEventProto::TrackedObject::PPAPI_PLUGIN; | 
| +    case content::PROCESS_TYPE_PPAPI_BROKER: | 
| +      return ProfilerEventProto::TrackedObject::PPAPI_BROKER; | 
| +    default: | 
| +      NOTREACHED(); | 
| +      return ProfilerEventProto::TrackedObject::UNKNOWN; | 
| +  } | 
| +} | 
| + | 
| // Returns the plugin preferences corresponding for this user, if available. | 
| // If multiple user profiles are loaded, returns the preferences corresponding | 
| // to an arbitrary one of the profiles. | 
| @@ -181,6 +221,44 @@ void WriteFieldTrials(const std::vector<NameGroupId>& field_trial_ids, | 
| } | 
| } | 
|  | 
| +void WriteProfilerData(const ProcessDataSnapshot& profiler_data, | 
| +                       content::ProcessType process_type, | 
| +                       ProfilerEventProto* performance_profile) { | 
| +  for (std::vector<tracked_objects::TaskSnapshot>::const_iterator it = | 
| +           profiler_data.tasks.begin(); | 
| +       it != profiler_data.tasks.end(); ++it) { | 
| +    std::string ignored; | 
| +    uint64 birth_thread_name_hash; | 
| +    uint64 exec_thread_name_hash; | 
| +    uint64 source_file_name_hash; | 
| +    uint64 source_function_name_hash; | 
| +    MetricsLogBase::CreateHashes(it->birth.thread_name, | 
| +                                 &ignored, &birth_thread_name_hash); | 
| +    MetricsLogBase::CreateHashes(it->death_thread_name, | 
| +                                 &ignored, &exec_thread_name_hash); | 
| +    MetricsLogBase::CreateHashes(it->birth.location.function_name, | 
| +                                 &ignored, &source_file_name_hash); | 
| +    MetricsLogBase::CreateHashes(it->birth.location.file_name, | 
| +                                 &ignored, &source_function_name_hash); | 
| + | 
| +    const tracked_objects::DeathDataSnapshot& death_data = it->death_data; | 
| +    ProfilerEventProto::TrackedObject* tracked_object = | 
| +        performance_profile->add_tracked_object(); | 
| +    tracked_object->set_birth_thread_name_hash(birth_thread_name_hash); | 
| +    tracked_object->set_exec_thread_name_hash(exec_thread_name_hash); | 
| +    tracked_object->set_source_file_name_hash(source_file_name_hash); | 
| +    tracked_object->set_source_function_name_hash(source_function_name_hash); | 
| +    tracked_object->set_source_line_number(it->birth.location.line_number); | 
| +    tracked_object->set_exec_count(death_data.count); | 
| +    tracked_object->set_exec_time_total(death_data.run_duration_sum); | 
| +    tracked_object->set_exec_time_sampled(death_data.run_duration_sample); | 
| +    tracked_object->set_queue_time_total(death_data.queue_duration_sum); | 
| +    tracked_object->set_queue_time_sampled(death_data.queue_duration_sample); | 
| +    tracked_object->set_process_type(AsProtobufProcessType(process_type)); | 
| +    tracked_object->set_process_id(profiler_data.process_id); | 
| +  } | 
| +} | 
| + | 
| }  // namespace | 
|  | 
| static base::LazyInstance<std::string>::Leaky | 
| @@ -704,6 +782,30 @@ void MetricsLog::RecordEnvironmentProto( | 
| WriteFieldTrials(field_trial_ids, system_profile); | 
| } | 
|  | 
| +void MetricsLog::RecordProfilerData( | 
| +    const tracked_objects::ProcessDataSnapshot& process_data, | 
| +    content::ProcessType process_type) { | 
| +  DCHECK(!locked()); | 
| + | 
| +  if (tracked_objects::GetAlternateTimeSource()) { | 
| +    // We currently only support the default time source, wall clock time. | 
| +    return; | 
| +  } | 
| + | 
| +  ProfilerEventProto* profile; | 
| +  if (!uma_proto()->profiler_event_size()) { | 
| +    // For the first process's data, add a new field to the protocol buffer. | 
| +    profile = uma_proto()->add_profiler_event(); | 
| +    profile->set_profile_type(ProfilerEventProto::STARTUP_PROFILE); | 
| +    profile->set_time_source(ProfilerEventProto::WALL_CLOCK_TIME); | 
| +  } else { | 
| +    // For the remaining calls, re-use the existing field. | 
| +    profile = uma_proto()->mutable_profiler_event(0); | 
| +  } | 
| + | 
| +  WriteProfilerData(process_data, process_type, profile); | 
| +} | 
| + | 
| void MetricsLog::WriteAllProfilesMetrics( | 
| const DictionaryValue& all_profiles_metrics) { | 
| const std::string profile_prefix(prefs::kProfilePrefix); | 
|  |