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

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

Issue 2546653002: Store and retrieve features from shared memory (Closed)
Patch Set: removing log statements 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"
11 #include "base/build_time.h" 11 #include "base/build_time.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/feature_list.h"
14 #include "base/logging.h" 13 #include "base/logging.h"
15 #include "base/metrics/field_trial_param_associator.h" 14 #include "base/metrics/field_trial_param_associator.h"
16 #include "base/pickle.h" 15 #include "base/pickle.h"
17 #include "base/process/memory.h" 16 #include "base/process/memory.h"
18 #include "base/rand_util.h" 17 #include "base/rand_util.h"
19 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
23 22
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 trials_string_piece.substr(next_item, name_end - next_item); 240 trials_string_piece.substr(next_item, name_end - next_item);
242 entry.group_name = 241 entry.group_name =
243 trials_string_piece.substr(name_end + 1, group_name_end - name_end - 1); 242 trials_string_piece.substr(name_end + 1, group_name_end - name_end - 1);
244 next_item = group_name_end + 1; 243 next_item = group_name_end + 1;
245 244
246 entries->push_back(std::move(entry)); 245 entries->push_back(std::move(entry));
247 } 246 }
248 return true; 247 return true;
249 } 248 }
250 249
251 void AddForceFieldTrialsFlag(CommandLine* cmd_line) { 250 void AddFeatureAndFieldTrialFlags(const char* enable_features_switch,
251 const char* disable_features_switch,
252 CommandLine* cmd_line) {
253 std::string enabled_features;
254 std::string disabled_features;
255 FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features,
256 &disabled_features);
257
258 if (!enabled_features.empty())
259 cmd_line->AppendSwitchASCII(enable_features_switch, enabled_features);
260 if (!disabled_features.empty())
261 cmd_line->AppendSwitchASCII(disable_features_switch, disabled_features);
262
252 std::string field_trial_states; 263 std::string field_trial_states;
253 FieldTrialList::AllStatesToString(&field_trial_states); 264 FieldTrialList::AllStatesToString(&field_trial_states);
254 if (!field_trial_states.empty()) { 265 if (!field_trial_states.empty()) {
255 cmd_line->AppendSwitchASCII(switches::kForceFieldTrials, 266 cmd_line->AppendSwitchASCII(switches::kForceFieldTrials,
256 field_trial_states); 267 field_trial_states);
257 } 268 }
258 } 269 }
259 270
260 #if defined(OS_WIN) 271 #if defined(OS_WIN)
261 HANDLE CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) { 272 HANDLE CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 #endif 809 #endif
799 810
800 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { 811 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
801 bool result = FieldTrialList::CreateTrialsFromString( 812 bool result = FieldTrialList::CreateTrialsFromString(
802 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), 813 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials),
803 std::set<std::string>()); 814 std::set<std::string>());
804 DCHECK(result); 815 DCHECK(result);
805 } 816 }
806 } 817 }
807 818
819 // static
820 void FieldTrialList::CreateFeaturesFromCommandLine(
821 const base::CommandLine& command_line,
822 const char* enable_features_switch,
823 const char* disable_features_switch,
824 FeatureList* feature_list) {
825 // Fallback to command line if not using shared memory.
826 if (!kUseSharedMemoryForFieldTrials ||
827 !global_->field_trial_allocator_.get()) {
828 return feature_list->InitializeFromCommandLine(
829 command_line.GetSwitchValueASCII(enable_features_switch),
830 command_line.GetSwitchValueASCII(disable_features_switch));
831 }
832
833 feature_list->InitializeFromSharedMemory(
834 global_->field_trial_allocator_.get());
835 }
836
808 #if defined(POSIX_WITH_ZYGOTE) 837 #if defined(POSIX_WITH_ZYGOTE)
809 // static 838 // static
810 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) { 839 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
811 if (!kUseSharedMemoryForFieldTrials) 840 if (!kUseSharedMemoryForFieldTrials)
812 return false; 841 return false;
813 842
814 if (fd_key == -1) 843 if (fd_key == -1)
815 return false; 844 return false;
816 845
817 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key); 846 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key);
(...skipping 29 matching lines...) Expand all
847 // We check for an invalid handle where this gets called. 876 // We check for an invalid handle where this gets called.
848 return global_->readonly_allocator_handle_; 877 return global_->readonly_allocator_handle_;
849 } 878 }
850 return kInvalidPlatformFile; 879 return kInvalidPlatformFile;
851 } 880 }
852 #endif 881 #endif
853 882
854 // static 883 // static
855 void FieldTrialList::CopyFieldTrialStateToFlags( 884 void FieldTrialList::CopyFieldTrialStateToFlags(
856 const char* field_trial_handle_switch, 885 const char* field_trial_handle_switch,
886 const char* enable_features_switch,
887 const char* disable_features_switch,
857 CommandLine* cmd_line) { 888 CommandLine* cmd_line) {
858 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However, 889 // TODO(lawrencewu): Ideally, having the global would be guaranteed. However,
859 // content browser tests currently don't create a FieldTrialList because they 890 // content browser tests currently don't create a FieldTrialList because they
860 // don't run ChromeBrowserMainParts code where it's done for Chrome. 891 // don't run ChromeBrowserMainParts code where it's done for Chrome.
861 if (!global_) 892 // Some tests depend on the enable and disable features flag switch, though,
893 // so we can still add those even though AllStatesToString() will be a no-op.
894 if (!global_) {
895 AddFeatureAndFieldTrialFlags(enable_features_switch,
896 disable_features_switch, cmd_line);
862 return; 897 return;
898 }
863 899
864 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) 900 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE)
865 // Use shared memory to pass the state if the feature is enabled, otherwise 901 // Use shared memory to pass the state if the feature is enabled, otherwise
866 // fallback to passing it via the command line as a string. 902 // fallback to passing it via the command line as a string.
867 if (kUseSharedMemoryForFieldTrials) { 903 if (kUseSharedMemoryForFieldTrials) {
868 InstantiateFieldTrialAllocatorIfNeeded(); 904 InstantiateFieldTrialAllocatorIfNeeded();
869 // If the readonly handle didn't get duplicated properly, then fallback to 905 // If the readonly handle didn't get duplicated properly, then fallback to
870 // original behavior. 906 // original behavior.
871 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) { 907 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) {
872 AddForceFieldTrialsFlag(cmd_line); 908 AddFeatureAndFieldTrialFlags(enable_features_switch,
909 disable_features_switch, cmd_line);
873 return; 910 return;
874 } 911 }
875 912
876 global_->field_trial_allocator_->UpdateTrackingHistograms(); 913 global_->field_trial_allocator_->UpdateTrackingHistograms();
877 914
878 #if defined(OS_WIN) 915 #if defined(OS_WIN)
879 // We need to pass a named anonymous handle to shared memory over the 916 // We need to pass a named anonymous handle to shared memory over the
880 // command line on Windows, since the child doesn't know which of the 917 // command line on Windows, since the child doesn't know which of the
881 // handles it inherited it should open. On POSIX, we don't need to do this 918 // handles it inherited it should open. On POSIX, we don't need to do this
882 // -- we dup the fd into a fixed fd kFieldTrialDescriptor, so we can just 919 // -- we dup the fd into a fixed fd kFieldTrialDescriptor, so we can just
883 // look it up there. 920 // look it up there.
884 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We 921 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We
885 // basically cast the handle into an int (uintptr_t, to be exact), stringify 922 // basically cast the handle into an int (uintptr_t, to be exact), stringify
886 // the int, and pass it as a command-line flag. The child process will do 923 // the int, and pass it as a command-line flag. The child process will do
887 // the reverse conversions to retrieve the handle. See 924 // the reverse conversions to retrieve the handle. See
888 // http://stackoverflow.com/a/153077 925 // http://stackoverflow.com/a/153077
889 auto uintptr_handle = 926 auto uintptr_handle =
890 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_); 927 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_);
891 std::string field_trial_handle = std::to_string(uintptr_handle); 928 std::string field_trial_handle = std::to_string(uintptr_handle);
892 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle); 929 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle);
893 #endif 930 #endif
894 return; 931 return;
895 } 932 }
896 #endif 933 #endif
897 934
898 AddForceFieldTrialsFlag(cmd_line); 935 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch,
936 cmd_line);
899 } 937 }
900 938
901 // static 939 // static
902 FieldTrial* FieldTrialList::CreateFieldTrial( 940 FieldTrial* FieldTrialList::CreateFieldTrial(
903 const std::string& name, 941 const std::string& name,
904 const std::string& group_name) { 942 const std::string& group_name) {
905 DCHECK(global_); 943 DCHECK(global_);
906 DCHECK_GE(name.size(), 0u); 944 DCHECK_GE(name.size(), 0u);
907 DCHECK_GE(group_name.size(), 0u); 945 DCHECK_GE(group_name.size(), 0u);
908 if (name.empty() || group_name.empty() || !global_) 946 if (name.empty() || group_name.empty() || !global_)
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 1202
1165 global_->field_trial_allocator_.reset( 1203 global_->field_trial_allocator_.reset(
1166 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false)); 1204 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false));
1167 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); 1205 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
1168 1206
1169 // Add all existing field trials. 1207 // Add all existing field trials.
1170 for (const auto& registered : global_->registered_) { 1208 for (const auto& registered : global_->registered_) {
1171 AddToAllocatorWhileLocked(registered.second); 1209 AddToAllocatorWhileLocked(registered.second);
1172 } 1210 }
1173 1211
1212 // Add all existing features.
1213 FeatureList::GetInstance()->AddFeaturesToAllocator(
1214 global_->field_trial_allocator_.get());
1215
1174 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) 1216 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE)
1175 // Set |readonly_allocator_handle_| so we can pass it to be inherited and 1217 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
1176 // via the command line. 1218 // via the command line.
1177 global_->readonly_allocator_handle_ = 1219 global_->readonly_allocator_handle_ =
1178 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 1220 CreateReadOnlyHandle(global_->field_trial_allocator_.get());
1179 #endif 1221 #endif
1180 } 1222 }
1181 #endif 1223 #endif
1182 1224
1183 // static 1225 // static
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 return; 1321 return;
1280 } 1322 }
1281 AutoLock auto_lock(global_->lock_); 1323 AutoLock auto_lock(global_->lock_);
1282 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1324 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1283 trial->AddRef(); 1325 trial->AddRef();
1284 trial->SetTrialRegistered(); 1326 trial->SetTrialRegistered();
1285 global_->registered_[trial->trial_name()] = trial; 1327 global_->registered_[trial->trial_name()] = trial;
1286 } 1328 }
1287 1329
1288 } // namespace base 1330 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698