1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/memory/discardable_memory.h" 6 7 #include "base/feature_list.h" 8 #include "base/memory/discardable_memory_internal.h" 9 #include "base/memory/madv_free_discardable_memory_posix.h" 10 #include "base/metrics/field_trial_params.h" 11 #include "base/notreached.h" 12 #include "build/build_config.h" 13 14 #if BUILDFLAG(IS_ANDROID) 15 #include "third_party/ashmem/ashmem.h" 16 #endif // BUILDFLAG(IS_ANDROID) 17 18 namespace base { 19 20 namespace features { 21 #if BUILDFLAG(IS_POSIX) 22 // Feature flag allowing the use of MADV_FREE discardable memory when there are 23 // multiple supported discardable memory backings. 24 BASE_FEATURE(kMadvFreeDiscardableMemory, 25 "MadvFreeDiscardableMemory", 26 base::FEATURE_DISABLED_BY_DEFAULT); 27 #endif // BUILDFLAG(IS_POSIX) 28 29 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 30 BASE_FEATURE(kDiscardableMemoryBackingTrial, 31 "DiscardableMemoryBackingTrial", 32 base::FEATURE_DISABLED_BY_DEFAULT); 33 34 35 #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || 36 // BUILDFLAG(IS_CHROMEOS) 37 38 } // namespace features 39 40 namespace { 41 42 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 43 GetBackingForFieldTrial()44DiscardableMemoryBacking GetBackingForFieldTrial() { 45 DiscardableMemoryTrialGroup trial_group = 46 GetDiscardableMemoryBackingFieldTrialGroup(); 47 switch (trial_group) { 48 case DiscardableMemoryTrialGroup::kEmulatedSharedMemory: 49 case DiscardableMemoryTrialGroup::kAshmem: 50 return DiscardableMemoryBacking::kSharedMemory; 51 case DiscardableMemoryTrialGroup::kMadvFree: 52 return DiscardableMemoryBacking::kMadvFree; 53 } 54 NOTREACHED(); 55 } 56 #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || 57 // BUILDFLAG(IS_CHROMEOS) 58 59 } // namespace 60 61 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 62 63 // Probe capabilities of this device to determine whether we should participate 64 // in the discardable memory backing trial. DiscardableMemoryBackingFieldTrialIsEnabled()65bool DiscardableMemoryBackingFieldTrialIsEnabled() { 66 #if BUILDFLAG(IS_ANDROID) 67 if (!ashmem_device_is_supported()) 68 return false; 69 #endif // BUILDFLAG(IS_ANDROID) 70 if (base::GetMadvFreeSupport() != base::MadvFreeSupport::kSupported) 71 return false; 72 73 // IMPORTANT: Only query the feature after we determine the device has the 74 // capabilities required, which will have the side-effect of assigning a 75 // trial-group. 76 return base::FeatureList::IsEnabled(features::kDiscardableMemoryBackingTrial); 77 } 78 GetDiscardableMemoryBackingFieldTrialGroup()79DiscardableMemoryTrialGroup GetDiscardableMemoryBackingFieldTrialGroup() { 80 DCHECK(DiscardableMemoryBackingFieldTrialIsEnabled()); 81 return features::kDiscardableMemoryBackingParam.Get(); 82 } 83 #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || 84 // BUILDFLAG(IS_CHROMEOS) 85 86 DiscardableMemory::DiscardableMemory() = default; 87 88 DiscardableMemory::~DiscardableMemory() = default; 89 GetDiscardableMemoryBacking()90DiscardableMemoryBacking GetDiscardableMemoryBacking() { 91 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 92 if (DiscardableMemoryBackingFieldTrialIsEnabled()) { 93 return GetBackingForFieldTrial(); 94 } 95 #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || 96 // BUILDFLAG(IS_CHROMEOS) 97 98 #if BUILDFLAG(IS_ANDROID) 99 if (ashmem_device_is_supported()) 100 return DiscardableMemoryBacking::kSharedMemory; 101 #endif // BUILDFLAG(IS_ANDROID) 102 103 #if BUILDFLAG(IS_POSIX) 104 if (base::FeatureList::IsEnabled( 105 base::features::kMadvFreeDiscardableMemory) && 106 base::GetMadvFreeSupport() == base::MadvFreeSupport::kSupported) { 107 return DiscardableMemoryBacking::kMadvFree; 108 } 109 #endif // BUILDFLAG(IS_POSIX) 110 111 return DiscardableMemoryBacking::kSharedMemory; 112 } 113 114 } // namespace base 115