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

Side by Side Diff: base/metrics/field_trial.cc

Issue 2546653002: Store and retrieve features from shared memory (Closed)
Patch Set: Created 4 years 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/metrics/field_trial.h" 5 #include "base/metrics/field_trial.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/base_switches.h" 10 #include "base/base_switches.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // This also doesn't allocate all 128 KiB at once -- the pages only get mapped 59 // This also doesn't allocate all 128 KiB at once -- the pages only get mapped
60 // to physical memory when they are touched. If the size of the allocated field 60 // to physical memory when they are touched. If the size of the allocated field
61 // trials does get larger than 128 KiB, then we will drop some field trials in 61 // trials does get larger than 128 KiB, then we will drop some field trials in
62 // child processes, leading to an inconsistent view between browser and child 62 // child processes, leading to an inconsistent view between browser and child
63 // processes and possibly causing crashes (see crbug.com/661617). 63 // processes and possibly causing crashes (see crbug.com/661617).
64 #if !defined(OS_NACL) 64 #if !defined(OS_NACL)
65 const size_t kFieldTrialAllocationSize = 128 << 10; // 128 KiB 65 const size_t kFieldTrialAllocationSize = 128 << 10; // 128 KiB
66 #endif 66 #endif
67 67
68 // We create one FieldTrialEntry per field trial in shared memory, via 68 // We create one FieldTrialEntry per field trial in shared memory, via
69 // AddToAllocatorWhileLocked. The FieldTrialEntry is followed by a base::Pickle 69 // AddTrialToAllocatorWhileLocked. The FieldTrialEntry is followed by a
70 // object that we unpickle and read from. Any changes to this structure requires 70 // base::Pickle object that we unpickle and read from. Any changes to this
71 // a bump in kFieldTrialType id defined above. 71 // structure requires a bump in kFieldTrialType id defined above.
72 struct FieldTrialEntry { 72 struct FieldTrialEntry {
73 // Expected size for 32/64-bit check. 73 // Expected size for 32/64-bit check.
74 static constexpr size_t kExpectedInstanceSize = 8; 74 static constexpr size_t kExpectedInstanceSize = 8;
75 75
76 // Whether or not this field trial is activated. This is really just a boolean 76 // Whether or not this field trial is activated. This is really just a boolean
77 // but marked as a uint32_t for portability reasons. 77 // but marked as a uint32_t for portability reasons.
78 uint32_t activated; 78 uint32_t activated;
79 79
80 // Size of the pickled structure, NOT the total size of this entry. 80 // Size of the pickled structure, NOT the total size of this entry.
81 uint32_t size; 81 uint32_t size;
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 if (CreateTrialsFromDescriptor(fd_key)) 732 if (CreateTrialsFromDescriptor(fd_key))
733 return; 733 return;
734 #endif 734 #endif
735 735
736 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { 736 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
737 bool result = FieldTrialList::CreateTrialsFromString( 737 bool result = FieldTrialList::CreateTrialsFromString(
738 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), 738 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials),
739 std::set<std::string>()); 739 std::set<std::string>());
740 DCHECK(result); 740 DCHECK(result);
741 } 741 }
742
743 // TODO(lawrencewu): rename CreateTrialsFromCommandLine to
744 // CreateTrialsAndFeaturesFromCommandLine, cause that's what we're doing.
745 FeatureList::GetInstance()->InitializeFromSharedMemory(
746 global_->field_trial_allocator_.get());
742 } 747 }
743 748
744 #if defined(POSIX_WITH_ZYGOTE) 749 #if defined(POSIX_WITH_ZYGOTE)
745 // static 750 // static
746 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) { 751 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
747 if (!kUseSharedMemoryForFieldTrials) 752 if (!kUseSharedMemoryForFieldTrials)
748 return false; 753 return false;
749 754
750 if (fd_key == -1) 755 if (fd_key == -1)
751 return false; 756 return false;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 if (!global_) 877 if (!global_)
873 return; 878 return;
874 global_->observer_list_->RemoveObserver(observer); 879 global_->observer_list_->RemoveObserver(observer);
875 } 880 }
876 881
877 // static 882 // static
878 void FieldTrialList::OnGroupFinalized(bool is_locked, FieldTrial* field_trial) { 883 void FieldTrialList::OnGroupFinalized(bool is_locked, FieldTrial* field_trial) {
879 if (!global_) 884 if (!global_)
880 return; 885 return;
881 if (is_locked) { 886 if (is_locked) {
882 AddToAllocatorWhileLocked(field_trial); 887 AddTrialToAllocatorWhileLocked(field_trial);
883 } else { 888 } else {
884 AutoLock auto_lock(global_->lock_); 889 AutoLock auto_lock(global_->lock_);
885 AddToAllocatorWhileLocked(field_trial); 890 AddTrialToAllocatorWhileLocked(field_trial);
886 } 891 }
887 } 892 }
888 893
889 // static 894 // static
890 void FieldTrialList::NotifyFieldTrialGroupSelection(FieldTrial* field_trial) { 895 void FieldTrialList::NotifyFieldTrialGroupSelection(FieldTrial* field_trial) {
891 if (!global_) 896 if (!global_)
892 return; 897 return;
893 898
894 { 899 {
895 AutoLock auto_lock(global_->lock_); 900 AutoLock auto_lock(global_->lock_);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 1002
998 if (!shm->Map(kFieldTrialAllocationSize)) 1003 if (!shm->Map(kFieldTrialAllocationSize))
999 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); 1004 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize);
1000 1005
1001 global_->field_trial_allocator_.reset( 1006 global_->field_trial_allocator_.reset(
1002 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false)); 1007 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false));
1003 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); 1008 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
1004 1009
1005 // Add all existing field trials. 1010 // Add all existing field trials.
1006 for (const auto& registered : global_->registered_) { 1011 for (const auto& registered : global_->registered_) {
1007 AddToAllocatorWhileLocked(registered.second); 1012 AddTrialToAllocatorWhileLocked(registered.second);
1008 } 1013 }
1009 1014
1015 // Add all existing features.
1016 FeatureList::GetInstance()->AddFeaturesToAllocator(
1017 global_->field_trial_allocator_.get());
1018
1010 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) 1019 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE)
1011 // Set |readonly_allocator_handle_| so we can pass it to be inherited and 1020 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
1012 // via the command line. 1021 // via the command line.
1013 global_->readonly_allocator_handle_ = 1022 global_->readonly_allocator_handle_ =
1014 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 1023 CreateReadOnlyHandle(global_->field_trial_allocator_.get());
1015 #endif 1024 #endif
1016 } 1025 }
1017 #endif 1026 #endif
1018 1027
1019 // static 1028 // static
1020 void FieldTrialList::AddToAllocatorWhileLocked(FieldTrial* field_trial) { 1029 void FieldTrialList::AddTrialToAllocatorWhileLocked(FieldTrial* field_trial) {
1021 FieldTrialAllocator* allocator = global_->field_trial_allocator_.get(); 1030 FieldTrialAllocator* allocator = global_->field_trial_allocator_.get();
1022 1031
1023 // Don't do anything if the allocator hasn't been instantiated yet. 1032 // Don't do anything if the allocator hasn't been instantiated yet.
1024 if (allocator == nullptr) 1033 if (allocator == nullptr)
1025 return; 1034 return;
1026 1035
1027 // Or if the allocator is read only, which means we are in a child process and 1036 // Or if the allocator is read only, which means we are in a child process and
1028 // shouldn't be writing to it. 1037 // shouldn't be writing to it.
1029 if (allocator->IsReadonly()) 1038 if (allocator->IsReadonly())
1030 return; 1039 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 FieldTrialAllocator* allocator = global_->field_trial_allocator_.get(); 1077 FieldTrialAllocator* allocator = global_->field_trial_allocator_.get();
1069 1078
1070 // Check if we're in the child process and return early if so. 1079 // Check if we're in the child process and return early if so.
1071 if (allocator && allocator->IsReadonly()) 1080 if (allocator && allocator->IsReadonly())
1072 return; 1081 return;
1073 1082
1074 FieldTrial::FieldTrialRef ref = field_trial->ref_; 1083 FieldTrial::FieldTrialRef ref = field_trial->ref_;
1075 if (ref == FieldTrialAllocator::kReferenceNull) { 1084 if (ref == FieldTrialAllocator::kReferenceNull) {
1076 // It's fine to do this even if the allocator hasn't been instantiated 1085 // It's fine to do this even if the allocator hasn't been instantiated
1077 // yet -- it'll just return early. 1086 // yet -- it'll just return early.
1078 AddToAllocatorWhileLocked(field_trial); 1087 AddTrialToAllocatorWhileLocked(field_trial);
1079 } else { 1088 } else {
1080 // It's also okay to do this even though the callee doesn't have a lock -- 1089 // It's also okay to do this even though the callee doesn't have a lock --
1081 // the only thing that happens on a stale read here is a slight performance 1090 // the only thing that happens on a stale read here is a slight performance
1082 // hit from the child re-synchronizing activation state. 1091 // hit from the child re-synchronizing activation state.
1083 FieldTrialEntry* entry = 1092 FieldTrialEntry* entry =
1084 allocator->GetAsObject<FieldTrialEntry>(ref, kFieldTrialType); 1093 allocator->GetAsObject<FieldTrialEntry>(ref, kFieldTrialType);
1085 entry->activated = true; 1094 entry->activated = true;
1086 } 1095 }
1087 } 1096 }
1088 1097
(...skipping 22 matching lines...) Expand all
1111 return; 1120 return;
1112 } 1121 }
1113 AutoLock auto_lock(global_->lock_); 1122 AutoLock auto_lock(global_->lock_);
1114 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1123 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1115 trial->AddRef(); 1124 trial->AddRef();
1116 trial->SetTrialRegistered(); 1125 trial->SetTrialRegistered();
1117 global_->registered_[trial->trial_name()] = trial; 1126 global_->registered_[trial->trial_name()] = trial;
1118 } 1127 }
1119 1128
1120 } // namespace base 1129 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698