| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/feature_list.h" | 5 #include "base/feature_list.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // Pointer to the FeatureList instance singleton that was set via | 23 // Pointer to the FeatureList instance singleton that was set via |
| 24 // FeatureList::SetInstance(). Does not use base/memory/singleton.h in order to | 24 // FeatureList::SetInstance(). Does not use base/memory/singleton.h in order to |
| 25 // have more control over initialization timing. Leaky. | 25 // have more control over initialization timing. Leaky. |
| 26 FeatureList* g_instance = nullptr; | 26 FeatureList* g_instance = nullptr; |
| 27 | 27 |
| 28 // Tracks whether the FeatureList instance was initialized via an accessor. | 28 // Tracks whether the FeatureList instance was initialized via an accessor. |
| 29 bool g_initialized_from_accessor = false; | 29 bool g_initialized_from_accessor = false; |
| 30 | 30 |
| 31 const uint32_t kFeatureType = 0x06567CA6 + 1; // SHA1(FeatureEntry) v1 | |
| 32 | |
| 33 // An allocator entry for a feature in shared memory. The FeatureEntry is | 31 // An allocator entry for a feature in shared memory. The FeatureEntry is |
| 34 // followed by a base::Pickle object that contains the feature and trial name. | 32 // followed by a base::Pickle object that contains the feature and trial name. |
| 35 // Any changes to this structure requires a bump in kFeatureType defined above. | |
| 36 struct FeatureEntry { | 33 struct FeatureEntry { |
| 34 // SHA1(FeatureEntry): Increment this if structure changes! |
| 35 static constexpr uint32_t kPersistentTypeId = 0x06567CA6 + 1; |
| 36 |
| 37 // Expected size for 32/64-bit check. | 37 // Expected size for 32/64-bit check. |
| 38 static constexpr size_t kExpectedInstanceSize = 8; | 38 static constexpr size_t kExpectedInstanceSize = 8; |
| 39 | 39 |
| 40 // Specifies whether a feature override enables or disables the feature. Same | 40 // Specifies whether a feature override enables or disables the feature. Same |
| 41 // values as the OverrideState enum in feature_list.h | 41 // values as the OverrideState enum in feature_list.h |
| 42 uint32_t override_state; | 42 uint32_t override_state; |
| 43 | 43 |
| 44 // Size of the pickled structure, NOT the total size of this entry. | 44 // Size of the pickled structure, NOT the total size of this entry. |
| 45 uint32_t pickle_size; | 45 uint32_t pickle_size; |
| 46 | 46 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 RegisterOverridesFromCommandLine(enable_features, OVERRIDE_ENABLE_FEATURE); | 91 RegisterOverridesFromCommandLine(enable_features, OVERRIDE_ENABLE_FEATURE); |
| 92 | 92 |
| 93 initialized_from_command_line_ = true; | 93 initialized_from_command_line_ = true; |
| 94 } | 94 } |
| 95 | 95 |
| 96 void FeatureList::InitializeFromSharedMemory( | 96 void FeatureList::InitializeFromSharedMemory( |
| 97 PersistentMemoryAllocator* allocator) { | 97 PersistentMemoryAllocator* allocator) { |
| 98 DCHECK(!initialized_); | 98 DCHECK(!initialized_); |
| 99 | 99 |
| 100 PersistentMemoryAllocator::Iterator iter(allocator); | 100 PersistentMemoryAllocator::Iterator iter(allocator); |
| 101 | 101 const FeatureEntry* entry; |
| 102 PersistentMemoryAllocator::Reference ref; | 102 while ((entry = iter.GetNextOfObject<FeatureEntry>()) != nullptr) { |
| 103 while ((ref = iter.GetNextOfType(kFeatureType)) != | |
| 104 PersistentMemoryAllocator::kReferenceNull) { | |
| 105 const FeatureEntry* entry = | |
| 106 allocator->GetAsObject<const FeatureEntry>(ref, kFeatureType); | |
| 107 | |
| 108 OverrideState override_state = | 103 OverrideState override_state = |
| 109 static_cast<OverrideState>(entry->override_state); | 104 static_cast<OverrideState>(entry->override_state); |
| 110 | 105 |
| 111 StringPiece feature_name; | 106 StringPiece feature_name; |
| 112 StringPiece trial_name; | 107 StringPiece trial_name; |
| 113 if (!entry->GetFeatureAndTrialName(&feature_name, &trial_name)) | 108 if (!entry->GetFeatureAndTrialName(&feature_name, &trial_name)) |
| 114 continue; | 109 continue; |
| 115 | 110 |
| 116 FieldTrial* trial = FieldTrialList::Find(trial_name.as_string()); | 111 FieldTrial* trial = FieldTrialList::Find(trial_name.as_string()); |
| 117 RegisterOverride(feature_name, override_state, trial); | 112 RegisterOverride(feature_name, override_state, trial); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 void FeatureList::AddFeaturesToAllocator(PersistentMemoryAllocator* allocator) { | 158 void FeatureList::AddFeaturesToAllocator(PersistentMemoryAllocator* allocator) { |
| 164 DCHECK(initialized_); | 159 DCHECK(initialized_); |
| 165 | 160 |
| 166 for (const auto& override : overrides_) { | 161 for (const auto& override : overrides_) { |
| 167 Pickle pickle; | 162 Pickle pickle; |
| 168 pickle.WriteString(override.first); | 163 pickle.WriteString(override.first); |
| 169 if (override.second.field_trial) | 164 if (override.second.field_trial) |
| 170 pickle.WriteString(override.second.field_trial->trial_name()); | 165 pickle.WriteString(override.second.field_trial->trial_name()); |
| 171 | 166 |
| 172 size_t total_size = sizeof(FeatureEntry) + pickle.size(); | 167 size_t total_size = sizeof(FeatureEntry) + pickle.size(); |
| 173 PersistentMemoryAllocator::Reference ref = | 168 FeatureEntry* entry = allocator->AllocateObject<FeatureEntry>(total_size); |
| 174 allocator->Allocate(total_size, kFeatureType); | 169 if (!entry) |
| 175 if (!ref) | |
| 176 return; | 170 return; |
| 177 | 171 |
| 178 FeatureEntry* entry = | |
| 179 allocator->GetAsObject<FeatureEntry>(ref, kFeatureType); | |
| 180 entry->override_state = override.second.overridden_state; | 172 entry->override_state = override.second.overridden_state; |
| 181 entry->pickle_size = pickle.size(); | 173 entry->pickle_size = pickle.size(); |
| 182 | 174 |
| 183 char* dst = reinterpret_cast<char*>(entry) + sizeof(FeatureEntry); | 175 char* dst = reinterpret_cast<char*>(entry) + sizeof(FeatureEntry); |
| 184 memcpy(dst, pickle.data(), pickle.size()); | 176 memcpy(dst, pickle.data(), pickle.size()); |
| 185 | 177 |
| 186 allocator->MakeIterable(ref); | 178 allocator->MakeIterable(entry); |
| 187 } | 179 } |
| 188 } | 180 } |
| 189 | 181 |
| 190 void FeatureList::GetFeatureOverrides(std::string* enable_overrides, | 182 void FeatureList::GetFeatureOverrides(std::string* enable_overrides, |
| 191 std::string* disable_overrides) { | 183 std::string* disable_overrides) { |
| 192 DCHECK(initialized_); | 184 DCHECK(initialized_); |
| 193 | 185 |
| 194 enable_overrides->clear(); | 186 enable_overrides->clear(); |
| 195 disable_overrides->clear(); | 187 disable_overrides->clear(); |
| 196 | 188 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 return it->second == &feature; | 388 return it->second == &feature; |
| 397 } | 389 } |
| 398 | 390 |
| 399 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state, | 391 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state, |
| 400 FieldTrial* field_trial) | 392 FieldTrial* field_trial) |
| 401 : overridden_state(overridden_state), | 393 : overridden_state(overridden_state), |
| 402 field_trial(field_trial), | 394 field_trial(field_trial), |
| 403 overridden_by_field_trial(field_trial != nullptr) {} | 395 overridden_by_field_trial(field_trial != nullptr) {} |
| 404 | 396 |
| 405 } // namespace base | 397 } // namespace base |
| OLD | NEW |