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

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

Issue 2546653002: Store and retrieve features from shared memory (Closed)
Patch Set: ifdef InstantiateAllocator test out for ios 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,
862 return; 893 // so we can still add those even though AllStatesToString() will be a no-op.
894 if (!global_) {
895 return AddFeatureAndFieldTrialFlags(enable_features_switch,
Alexei Svitkine (slow) 2016/12/02 20:14:28 The function return value is void - so don't retur
lawrencewu 2016/12/02 20:36:32 Done.
896 disable_features_switch, cmd_line);
897 }
863 898
864 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) 899 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE)
865 // Use shared memory to pass the state if the feature is enabled, otherwise 900 // 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. 901 // fallback to passing it via the command line as a string.
867 if (kUseSharedMemoryForFieldTrials) { 902 if (kUseSharedMemoryForFieldTrials) {
868 InstantiateFieldTrialAllocatorIfNeeded(); 903 InstantiateFieldTrialAllocatorIfNeeded();
869 // If the readonly handle didn't get duplicated properly, then fallback to 904 // If the readonly handle didn't get duplicated properly, then fallback to
870 // original behavior. 905 // original behavior.
871 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) { 906 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) {
872 AddForceFieldTrialsFlag(cmd_line); 907 AddFeatureAndFieldTrialFlags(enable_features_switch,
908 disable_features_switch, cmd_line);
873 return; 909 return;
874 } 910 }
875 911
876 global_->field_trial_allocator_->UpdateTrackingHistograms(); 912 global_->field_trial_allocator_->UpdateTrackingHistograms();
877 913
878 #if defined(OS_WIN) 914 #if defined(OS_WIN)
879 // We need to pass a named anonymous handle to shared memory over the 915 // 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 916 // 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 917 // 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 918 // -- we dup the fd into a fixed fd kFieldTrialDescriptor, so we can just
883 // look it up there. 919 // look it up there.
884 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We 920 // 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 921 // 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 922 // the int, and pass it as a command-line flag. The child process will do
887 // the reverse conversions to retrieve the handle. See 923 // the reverse conversions to retrieve the handle. See
888 // http://stackoverflow.com/a/153077 924 // http://stackoverflow.com/a/153077
889 auto uintptr_handle = 925 auto uintptr_handle =
890 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_); 926 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_);
891 std::string field_trial_handle = std::to_string(uintptr_handle); 927 std::string field_trial_handle = std::to_string(uintptr_handle);
892 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle); 928 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle);
893 #endif 929 #endif
894 return; 930 return;
895 } 931 }
896 #endif 932 #endif
897 933
898 AddForceFieldTrialsFlag(cmd_line); 934 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch,
935 cmd_line);
899 } 936 }
900 937
901 // static 938 // static
902 FieldTrial* FieldTrialList::CreateFieldTrial( 939 FieldTrial* FieldTrialList::CreateFieldTrial(
903 const std::string& name, 940 const std::string& name,
904 const std::string& group_name) { 941 const std::string& group_name) {
905 DCHECK(global_); 942 DCHECK(global_);
906 DCHECK_GE(name.size(), 0u); 943 DCHECK_GE(name.size(), 0u);
907 DCHECK_GE(group_name.size(), 0u); 944 DCHECK_GE(group_name.size(), 0u);
908 if (name.empty() || group_name.empty() || !global_) 945 if (name.empty() || group_name.empty() || !global_)
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 1201
1165 global_->field_trial_allocator_.reset( 1202 global_->field_trial_allocator_.reset(
1166 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false)); 1203 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false));
1167 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); 1204 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
1168 1205
1169 // Add all existing field trials. 1206 // Add all existing field trials.
1170 for (const auto& registered : global_->registered_) { 1207 for (const auto& registered : global_->registered_) {
1171 AddToAllocatorWhileLocked(registered.second); 1208 AddToAllocatorWhileLocked(registered.second);
1172 } 1209 }
1173 1210
1211 // Add all existing features.
1212 FeatureList::GetInstance()->AddFeaturesToAllocator(
1213 global_->field_trial_allocator_.get());
1214
1174 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) 1215 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE)
1175 // Set |readonly_allocator_handle_| so we can pass it to be inherited and 1216 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
1176 // via the command line. 1217 // via the command line.
1177 global_->readonly_allocator_handle_ = 1218 global_->readonly_allocator_handle_ =
1178 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 1219 CreateReadOnlyHandle(global_->field_trial_allocator_.get());
1179 #endif 1220 #endif
1180 } 1221 }
1181 #endif 1222 #endif
1182 1223
1183 // static 1224 // static
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 return; 1320 return;
1280 } 1321 }
1281 AutoLock auto_lock(global_->lock_); 1322 AutoLock auto_lock(global_->lock_);
1282 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1323 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1283 trial->AddRef(); 1324 trial->AddRef();
1284 trial->SetTrialRegistered(); 1325 trial->SetTrialRegistered();
1285 global_->registered_[trial->trial_name()] = trial; 1326 global_->registered_[trial->trial_name()] = trial;
1286 } 1327 }
1287 1328
1288 } // namespace base 1329 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698