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

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

Issue 2633203002: Enable field trial shared memory segment on Android. (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « base/metrics/field_trial.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/field_trial_param_associator.h" 14 #include "base/metrics/field_trial_param_associator.h"
15 #include "base/process/memory.h" 15 #include "base/process/memory.h"
16 #include "base/rand_util.h" 16 #include "base/rand_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 21
22 // On systems that use the zygote process to spawn child processes, we must 22 // On POSIX, the fd is shared using the mapping in GlobalDescriptors.
23 // retrieve the correct fd using the mapping in GlobalDescriptors. 23 #if defined(OS_POSIX) && !defined(OS_NACL)
24 #if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_MACOSX) && \
25 !defined(OS_ANDROID)
26 #define POSIX_WITH_ZYGOTE 1
27 #endif
28
29 #if defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX)
30 #include "base/posix/global_descriptors.h" 24 #include "base/posix/global_descriptors.h"
31 #endif 25 #endif
32 26
33 namespace base { 27 namespace base {
34 28
35 namespace { 29 namespace {
36 30
37 // Define a separator character to use when creating a persistent form of an 31 // Define a separator character to use when creating a persistent form of an
38 // instance. This is intended for use as a command line argument, passed to a 32 // instance. This is intended for use as a command line argument, passed to a
39 // second process to mimic our state (i.e., provide the same group name). 33 // second process to mimic our state (i.e., provide the same group name).
(...skipping 16 matching lines...) Expand all
56 // Constants for the field trial allocator. 50 // Constants for the field trial allocator.
57 const char kAllocatorName[] = "FieldTrialAllocator"; 51 const char kAllocatorName[] = "FieldTrialAllocator";
58 52
59 // We allocate 128 KiB to hold all the field trial data. This should be enough, 53 // We allocate 128 KiB to hold all the field trial data. This should be enough,
60 // as most people use 3 - 25 KiB for field trials (as of 11/25/2016). 54 // as most people use 3 - 25 KiB for field trials (as of 11/25/2016).
61 // This also doesn't allocate all 128 KiB at once -- the pages only get mapped 55 // This also doesn't allocate all 128 KiB at once -- the pages only get mapped
62 // to physical memory when they are touched. If the size of the allocated field 56 // to physical memory when they are touched. If the size of the allocated field
63 // trials does get larger than 128 KiB, then we will drop some field trials in 57 // trials does get larger than 128 KiB, then we will drop some field trials in
64 // child processes, leading to an inconsistent view between browser and child 58 // child processes, leading to an inconsistent view between browser and child
65 // processes and possibly causing crashes (see crbug.com/661617). 59 // processes and possibly causing crashes (see crbug.com/661617).
66 #if !defined(OS_NACL)
67 const size_t kFieldTrialAllocationSize = 128 << 10; // 128 KiB 60 const size_t kFieldTrialAllocationSize = 128 << 10; // 128 KiB
68 #endif
69 61
70 // Writes out string1 and then string2 to pickle. 62 // Writes out string1 and then string2 to pickle.
71 bool WriteStringPair(Pickle* pickle, 63 bool WriteStringPair(Pickle* pickle,
72 const StringPiece& string1, 64 const StringPiece& string1,
73 const StringPiece& string2) { 65 const StringPiece& string2) {
74 if (!pickle->WriteString(string1)) 66 if (!pickle->WriteString(string1))
75 return false; 67 return false;
76 if (!pickle->WriteString(string2)) 68 if (!pickle->WriteString(string2))
77 return false; 69 return false;
78 return true; 70 return true;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 HANDLE src = allocator->shared_memory()->handle().GetHandle(); 203 HANDLE src = allocator->shared_memory()->handle().GetHandle();
212 ProcessHandle process = GetCurrentProcess(); 204 ProcessHandle process = GetCurrentProcess();
213 DWORD access = SECTION_MAP_READ | SECTION_QUERY; 205 DWORD access = SECTION_MAP_READ | SECTION_QUERY;
214 HANDLE dst; 206 HANDLE dst;
215 if (!::DuplicateHandle(process, src, process, &dst, access, true, 0)) 207 if (!::DuplicateHandle(process, src, process, &dst, access, true, 0))
216 return kInvalidPlatformFile; 208 return kInvalidPlatformFile;
217 return dst; 209 return dst;
218 } 210 }
219 #endif 211 #endif
220 212
221 #if defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX) 213 #if defined(OS_POSIX) && !defined(OS_NACL)
222 int CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) { 214 int CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
223 SharedMemoryHandle new_handle; 215 SharedMemoryHandle new_handle;
224 allocator->shared_memory()->ShareReadOnlyToProcess(GetCurrentProcessHandle(), 216 allocator->shared_memory()->ShareReadOnlyToProcess(GetCurrentProcessHandle(),
225 &new_handle); 217 &new_handle);
226 return SharedMemory::GetFdFromSharedMemoryHandle(new_handle); 218 return SharedMemory::GetFdFromSharedMemoryHandle(new_handle);
227 } 219 }
228 #endif 220 #endif
229 221
222 void OnOutOfMemory(size_t size) {
223 #if defined(OS_NACL)
224 NOTREACHED();
225 #else
226 TerminateBecauseOutOfMemory(size);
227 #endif
228 }
229
230 } // namespace 230 } // namespace
231 231
232 // statics 232 // statics
233 const int FieldTrial::kNotFinalized = -1; 233 const int FieldTrial::kNotFinalized = -1;
234 const int FieldTrial::kDefaultGroupNumber = 0; 234 const int FieldTrial::kDefaultGroupNumber = 0;
235 bool FieldTrial::enable_benchmarking_ = false; 235 bool FieldTrial::enable_benchmarking_ = false;
236 236
237 int FieldTrialList::kNoExpirationYear = 0; 237 int FieldTrialList::kNoExpirationYear = 0;
238 238
239 //------------------------------------------------------------------------------ 239 //------------------------------------------------------------------------------
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 772
773 #if defined(OS_WIN) 773 #if defined(OS_WIN)
774 if (cmd_line.HasSwitch(field_trial_handle_switch)) { 774 if (cmd_line.HasSwitch(field_trial_handle_switch)) {
775 std::string handle_switch = 775 std::string handle_switch =
776 cmd_line.GetSwitchValueASCII(field_trial_handle_switch); 776 cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
777 bool result = CreateTrialsFromHandleSwitch(handle_switch); 777 bool result = CreateTrialsFromHandleSwitch(handle_switch);
778 DCHECK(result); 778 DCHECK(result);
779 } 779 }
780 #endif 780 #endif
781 781
782 #if defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX) 782 #if defined(OS_POSIX) && !defined(OS_NACL)
783 // On POSIX, we check if the handle is valid by seeing if the browser process 783 // On POSIX, we check if the handle is valid by seeing if the browser process
784 // sent over the switch (we don't care about the value). Invalid handles 784 // sent over the switch (we don't care about the value). Invalid handles
785 // occur in some browser tests which don't initialize the allocator. 785 // occur in some browser tests which don't initialize the allocator.
786 if (cmd_line.HasSwitch(field_trial_handle_switch)) { 786 if (cmd_line.HasSwitch(field_trial_handle_switch)) {
787 bool result = CreateTrialsFromDescriptor(fd_key); 787 bool result = CreateTrialsFromDescriptor(fd_key);
788 DCHECK(result); 788 DCHECK(result);
789 } 789 }
790 #endif 790 #endif
791 791
792 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { 792 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
(...skipping 15 matching lines...) Expand all
808 !global_->field_trial_allocator_.get()) { 808 !global_->field_trial_allocator_.get()) {
809 return feature_list->InitializeFromCommandLine( 809 return feature_list->InitializeFromCommandLine(
810 command_line.GetSwitchValueASCII(enable_features_switch), 810 command_line.GetSwitchValueASCII(enable_features_switch),
811 command_line.GetSwitchValueASCII(disable_features_switch)); 811 command_line.GetSwitchValueASCII(disable_features_switch));
812 } 812 }
813 813
814 feature_list->InitializeFromSharedMemory( 814 feature_list->InitializeFromSharedMemory(
815 global_->field_trial_allocator_.get()); 815 global_->field_trial_allocator_.get());
816 } 816 }
817 817
818 #if defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX)
819 // static
820 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
821 if (!kUseSharedMemoryForFieldTrials)
822 return false;
823
824 if (fd_key == -1)
825 return false;
826
827 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key);
828 if (fd == -1)
829 return false;
830
831 #if defined(POSIX_WITH_ZYGOTE)
832 SharedMemoryHandle shm_handle(fd, true);
833 #elif defined(OS_MACOSX)
834 SharedMemoryHandle shm_handle(FileDescriptor(fd, true));
835 #endif
836
837 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle);
838 DCHECK(result);
839 return true;
840 }
841 #endif
842
843 #if defined(OS_WIN) 818 #if defined(OS_WIN)
844 // static 819 // static
845 void FieldTrialList::AppendFieldTrialHandleIfNeeded( 820 void FieldTrialList::AppendFieldTrialHandleIfNeeded(
846 HandlesToInheritVector* handles) { 821 HandlesToInheritVector* handles) {
847 if (!global_) 822 if (!global_)
848 return; 823 return;
849 if (kUseSharedMemoryForFieldTrials) { 824 if (kUseSharedMemoryForFieldTrials) {
850 InstantiateFieldTrialAllocatorIfNeeded(); 825 InstantiateFieldTrialAllocatorIfNeeded();
851 if (global_->readonly_allocator_handle_) 826 if (global_->readonly_allocator_handle_)
852 handles->push_back(global_->readonly_allocator_handle_); 827 handles->push_back(global_->readonly_allocator_handle_);
(...skipping 23 matching lines...) Expand all
876 // content browser tests currently don't create a FieldTrialList because they 851 // content browser tests currently don't create a FieldTrialList because they
877 // don't run ChromeBrowserMainParts code where it's done for Chrome. 852 // don't run ChromeBrowserMainParts code where it's done for Chrome.
878 // Some tests depend on the enable and disable features flag switch, though, 853 // Some tests depend on the enable and disable features flag switch, though,
879 // so we can still add those even though AllStatesToString() will be a no-op. 854 // so we can still add those even though AllStatesToString() will be a no-op.
880 if (!global_) { 855 if (!global_) {
881 AddFeatureAndFieldTrialFlags(enable_features_switch, 856 AddFeatureAndFieldTrialFlags(enable_features_switch,
882 disable_features_switch, cmd_line); 857 disable_features_switch, cmd_line);
883 return; 858 return;
884 } 859 }
885 860
886 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX)
887 // Use shared memory to pass the state if the feature is enabled, otherwise 861 // Use shared memory to pass the state if the feature is enabled, otherwise
888 // fallback to passing it via the command line as a string. 862 // fallback to passing it via the command line as a string.
889 if (kUseSharedMemoryForFieldTrials) { 863 if (kUseSharedMemoryForFieldTrials) {
890 InstantiateFieldTrialAllocatorIfNeeded(); 864 InstantiateFieldTrialAllocatorIfNeeded();
891 // If the readonly handle didn't get duplicated properly, then fallback to 865 // If the readonly handle didn't get duplicated properly, then fallback to
892 // original behavior. 866 // original behavior.
893 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) { 867 if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) {
894 AddFeatureAndFieldTrialFlags(enable_features_switch, 868 AddFeatureAndFieldTrialFlags(enable_features_switch,
895 disable_features_switch, cmd_line); 869 disable_features_switch, cmd_line);
896 return; 870 return;
897 } 871 }
898 872
899 global_->field_trial_allocator_->UpdateTrackingHistograms(); 873 global_->field_trial_allocator_->UpdateTrackingHistograms();
900 874
901 #if defined(OS_WIN) 875 #if defined(OS_WIN)
902 // We need to pass a named anonymous handle to shared memory over the 876 // We need to pass a named anonymous handle to shared memory over the
903 // command line on Windows, since the child doesn't know which of the 877 // command line on Windows, since the child doesn't know which of the
904 // handles it inherited it should open. 878 // handles it inherited it should open.
905 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We 879 // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We
906 // basically cast the handle into an int (uintptr_t, to be exact), stringify 880 // basically cast the handle into an int (uintptr_t, to be exact), stringify
907 // the int, and pass it as a command-line flag. The child process will do 881 // the int, and pass it as a command-line flag. The child process will do
908 // the reverse conversions to retrieve the handle. See 882 // the reverse conversions to retrieve the handle. See
909 // http://stackoverflow.com/a/153077 883 // http://stackoverflow.com/a/153077
910 auto uintptr_handle = 884 auto uintptr_handle =
911 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_); 885 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_);
912 std::string field_trial_handle = std::to_string(uintptr_handle); 886 std::string field_trial_handle = std::to_string(uintptr_handle);
913 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle); 887 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle);
914 #elif defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX) 888 #else
bcwhite 2017/01/18 19:24:34 How about: #elif defined(OS_POSIX) ... #else #err
Alexei Svitkine (slow) 2017/01/18 20:05:02 Done.
915 // On POSIX, we dup the fd into a fixed fd kFieldTrialDescriptor, so we 889 // On POSIX, we dup the fd into a fixed fd kFieldTrialDescriptor, so we
916 // don't have to pass over the handle (it's not even the right handle 890 // don't have to pass over the handle (it's not even the right handle
917 // anyways). But some browser tests don't create the allocator, so we need 891 // anyways). But some browser tests don't create the allocator, so we need
918 // to be able to distinguish valid and invalid handles. We do that by just 892 // to be able to distinguish valid and invalid handles. We do that by just
919 // checking that the flag is set with a dummy value. 893 // checking that the flag is set with a dummy value.
920 cmd_line->AppendSwitchASCII(field_trial_handle_switch, "1"); 894 cmd_line->AppendSwitchASCII(field_trial_handle_switch, "1");
921 #endif 895 #endif
922 return; 896 return;
923 } 897 }
924 #endif
925 898
926 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch, 899 AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch,
927 cmd_line); 900 cmd_line);
928 } 901 }
929 902
930 // static 903 // static
931 FieldTrial* FieldTrialList::CreateFieldTrial( 904 FieldTrial* FieldTrialList::CreateFieldTrial(
932 const std::string& name, 905 const std::string& name,
933 const std::string& group_name) { 906 const std::string& group_name) {
934 DCHECK(global_); 907 DCHECK(global_);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 // static 1115 // static
1143 bool FieldTrialList::CreateTrialsFromHandleSwitch( 1116 bool FieldTrialList::CreateTrialsFromHandleSwitch(
1144 const std::string& handle_switch) { 1117 const std::string& handle_switch) {
1145 int field_trial_handle = std::stoi(handle_switch); 1118 int field_trial_handle = std::stoi(handle_switch);
1146 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle); 1119 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle);
1147 SharedMemoryHandle shm_handle(handle, GetCurrentProcId()); 1120 SharedMemoryHandle shm_handle(handle, GetCurrentProcId());
1148 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle); 1121 return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle);
1149 } 1122 }
1150 #endif 1123 #endif
1151 1124
1152 #if !defined(OS_NACL) 1125 #if defined(OS_POSIX) && !defined(OS_NACL)
1126 // static
1127 bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
1128 if (!kUseSharedMemoryForFieldTrials)
1129 return false;
1130
1131 if (fd_key == -1)
1132 return false;
1133
1134 int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key);
1135 if (fd == -1)
1136 return false;
1137
1138 #if defined(OS_MACOSX) && !defined(OS_IOS)
1139 SharedMemoryHandle shm_handle(FileDescriptor(fd, true));
1140 #else
1141 SharedMemoryHandle shm_handle(fd, true);
1142 #endif
1143
1144 bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle);
1145 DCHECK(result);
1146 return true;
1147 }
1148 #endif
1149
1153 // static 1150 // static
1154 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle( 1151 bool FieldTrialList::CreateTrialsFromSharedMemoryHandle(
1155 SharedMemoryHandle shm_handle) { 1152 SharedMemoryHandle shm_handle) {
1156 // shm gets deleted when it gets out of scope, but that's OK because we need 1153 // shm gets deleted when it gets out of scope, but that's OK because we need
1157 // it only for the duration of this method. 1154 // it only for the duration of this method.
1158 std::unique_ptr<SharedMemory> shm(new SharedMemory(shm_handle, true)); 1155 std::unique_ptr<SharedMemory> shm(new SharedMemory(shm_handle, true));
1159 if (!shm.get()->Map(kFieldTrialAllocationSize)) 1156 if (!shm.get()->Map(kFieldTrialAllocationSize))
1160 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); 1157 OnOutOfMemory(kFieldTrialAllocationSize);
1161 1158
1162 return FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm)); 1159 return FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm));
1163 } 1160 }
1164 #endif
1165 1161
1166 // static 1162 // static
1167 bool FieldTrialList::CreateTrialsFromSharedMemory( 1163 bool FieldTrialList::CreateTrialsFromSharedMemory(
1168 std::unique_ptr<SharedMemory> shm) { 1164 std::unique_ptr<SharedMemory> shm) {
1169 global_->field_trial_allocator_.reset( 1165 global_->field_trial_allocator_.reset(
1170 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, true)); 1166 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, true));
1171 FieldTrialAllocator* shalloc = global_->field_trial_allocator_.get(); 1167 FieldTrialAllocator* shalloc = global_->field_trial_allocator_.get();
1172 FieldTrialAllocator::Iterator mem_iter(shalloc); 1168 FieldTrialAllocator::Iterator mem_iter(shalloc);
1173 1169
1174 const FieldTrial::FieldTrialEntry* entry; 1170 const FieldTrial::FieldTrialEntry* entry;
(...skipping 13 matching lines...) Expand all
1188 if (subtle::NoBarrier_Load(&entry->activated)) { 1184 if (subtle::NoBarrier_Load(&entry->activated)) {
1189 // Call |group()| to mark the trial as "used" and notify observers, if 1185 // Call |group()| to mark the trial as "used" and notify observers, if
1190 // any. This is useful to ensure that field trials created in child 1186 // any. This is useful to ensure that field trials created in child
1191 // processes are properly reported in crash reports. 1187 // processes are properly reported in crash reports.
1192 trial->group(); 1188 trial->group();
1193 } 1189 }
1194 } 1190 }
1195 return true; 1191 return true;
1196 } 1192 }
1197 1193
1198 #if !defined(OS_NACL)
1199 // static 1194 // static
1200 void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() { 1195 void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() {
1201 if (!global_) 1196 if (!global_)
1202 return; 1197 return;
1203 AutoLock auto_lock(global_->lock_); 1198 AutoLock auto_lock(global_->lock_);
1204 // Create the allocator if not already created and add all existing trials. 1199 // Create the allocator if not already created and add all existing trials.
1205 if (global_->field_trial_allocator_ != nullptr) 1200 if (global_->field_trial_allocator_ != nullptr)
1206 return; 1201 return;
1207 1202
1208 SharedMemoryCreateOptions options; 1203 SharedMemoryCreateOptions options;
1209 options.size = kFieldTrialAllocationSize; 1204 options.size = kFieldTrialAllocationSize;
1210 options.share_read_only = true; 1205 options.share_read_only = true;
1211 #if defined(OS_MACOSX) && !defined(OS_IOS) 1206 #if defined(OS_MACOSX) && !defined(OS_IOS)
1212 options.type = SharedMemoryHandle::POSIX; 1207 options.type = SharedMemoryHandle::POSIX;
1213 #endif 1208 #endif
1214 1209
1215 std::unique_ptr<SharedMemory> shm(new SharedMemory()); 1210 std::unique_ptr<SharedMemory> shm(new SharedMemory());
1216 if (!shm->Create(options)) 1211 if (!shm->Create(options))
1217 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); 1212 OnOutOfMemory(kFieldTrialAllocationSize);
1218 1213
1219 if (!shm->Map(kFieldTrialAllocationSize)) 1214 if (!shm->Map(kFieldTrialAllocationSize))
1220 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); 1215 OnOutOfMemory(kFieldTrialAllocationSize);
1221 1216
1222 global_->field_trial_allocator_.reset( 1217 global_->field_trial_allocator_.reset(
1223 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false)); 1218 new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false));
1224 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); 1219 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
1225 1220
1226 // Add all existing field trials. 1221 // Add all existing field trials.
1227 for (const auto& registered : global_->registered_) { 1222 for (const auto& registered : global_->registered_) {
1228 AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(), 1223 AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(),
1229 registered.second); 1224 registered.second);
1230 } 1225 }
1231 1226
1232 // Add all existing features. 1227 // Add all existing features.
1233 FeatureList::GetInstance()->AddFeaturesToAllocator( 1228 FeatureList::GetInstance()->AddFeaturesToAllocator(
1234 global_->field_trial_allocator_.get()); 1229 global_->field_trial_allocator_.get());
1235 1230
1236 #if defined(OS_WIN) || defined(POSIX_WITH_ZYGOTE) || defined(OS_MACOSX) 1231 #if !defined(OS_NACL)
1237 // Set |readonly_allocator_handle_| so we can pass it to be inherited and 1232 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
1238 // via the command line. 1233 // via the command line.
1239 global_->readonly_allocator_handle_ = 1234 global_->readonly_allocator_handle_ =
1240 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 1235 CreateReadOnlyHandle(global_->field_trial_allocator_.get());
1241 #endif 1236 #endif
1242 } 1237 }
1243 #endif
1244 1238
1245 // static 1239 // static
1246 void FieldTrialList::AddToAllocatorWhileLocked( 1240 void FieldTrialList::AddToAllocatorWhileLocked(
1247 PersistentMemoryAllocator* allocator, 1241 PersistentMemoryAllocator* allocator,
1248 FieldTrial* field_trial) { 1242 FieldTrial* field_trial) {
1249 // Don't do anything if the allocator hasn't been instantiated yet. 1243 // Don't do anything if the allocator hasn't been instantiated yet.
1250 if (allocator == nullptr) 1244 if (allocator == nullptr)
1251 return; 1245 return;
1252 1246
1253 // Or if the allocator is read only, which means we are in a child process and 1247 // Or if the allocator is read only, which means we are in a child process and
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 return; 1337 return;
1344 } 1338 }
1345 AutoLock auto_lock(global_->lock_); 1339 AutoLock auto_lock(global_->lock_);
1346 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1340 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1347 trial->AddRef(); 1341 trial->AddRef();
1348 trial->SetTrialRegistered(); 1342 trial->SetTrialRegistered();
1349 global_->registered_[trial->trial_name()] = trial; 1343 global_->registered_[trial->trial_name()] = trial;
1350 } 1344 }
1351 1345
1352 } // namespace base 1346 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698