Add FeatureEntry::GetPickledDataPtr() helper method

Pull some unrelated cleanup from a future spanification CL into a
standalone prequel CL. Provides clearer documentation about what is
happening in this code.

-- Do the same for FieldTrialEntry.

Change-Id: Ie8fbce1e16d6c00935ca5f601f96b172ead2e0ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5068187
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1230257}
diff --git a/base/feature_list.cc b/base/feature_list.cc
index 6575c52..4bfd546 100644
--- a/base/feature_list.cc
+++ b/base/feature_list.cc
@@ -138,19 +138,21 @@
   // Size of the pickled structure, NOT the total size of this entry.
   uint64_t pickle_size;
 
+  // Return a pointer to the pickled data area immediately following the entry.
+  char* GetPickledDataPtr() { return reinterpret_cast<char*>(this + 1); }
+  const char* GetPickledDataPtr() const {
+    return reinterpret_cast<const char*>(this + 1);
+  }
+
   // Reads the feature and trial name from the pickle. Calling this is only
   // valid on an initialized entry that's in shared memory.
   bool GetFeatureAndTrialName(StringPiece* feature_name,
                               StringPiece* trial_name) const {
-    const char* src =
-        reinterpret_cast<const char*>(this) + sizeof(FeatureEntry);
-
-    Pickle pickle(src, checked_cast<size_t>(pickle_size));
+    Pickle pickle(GetPickledDataPtr(), checked_cast<size_t>(pickle_size));
     PickleIterator pickle_iter(pickle);
-
-    if (!pickle_iter.ReadStringPiece(feature_name))
+    if (!pickle_iter.ReadStringPiece(feature_name)) {
       return false;
-
+    }
     // Return true because we are not guaranteed to have a trial name anyways.
     std::ignore = pickle_iter.ReadStringPiece(trial_name);
     return true;
@@ -406,9 +408,7 @@
 
     entry->override_state = override.second.overridden_state;
     entry->pickle_size = pickle.size();
-
-    char* dst = reinterpret_cast<char*>(entry) + sizeof(FeatureEntry);
-    memcpy(dst, pickle.data(), pickle.size());
+    memcpy(entry->GetPickledDataPtr(), pickle.data(), pickle.size());
 
     allocator->MakeIterable(entry);
   }
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 71e82c22..acba79f 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -238,10 +238,7 @@
 }
 
 PickleIterator FieldTrial::FieldTrialEntry::GetPickleIterator() const {
-  const char* src =
-      reinterpret_cast<const char*>(this) + sizeof(FieldTrialEntry);
-
-  Pickle pickle(src, checked_cast<size_t>(pickle_size));
+  Pickle pickle(GetPickledDataPtr(), checked_cast<size_t>(pickle_size));
   return PickleIterator(pickle);
 }
 
@@ -980,9 +977,7 @@
 
     // TODO(lawrencewu): Modify base::Pickle to be able to write over a section
     // in memory, so we can avoid this memcpy.
-    char* dst = reinterpret_cast<char*>(new_entry) +
-                sizeof(FieldTrial::FieldTrialEntry);
-    memcpy(dst, pickle.data(), pickle.size());
+    memcpy(new_entry->GetPickledDataPtr(), pickle.data(), pickle.size());
 
     // Update the ref on the field trial and add it to the list to be made
     // iterable.
@@ -1320,9 +1315,7 @@
 
   // TODO(lawrencewu): Modify base::Pickle to be able to write over a section in
   // memory, so we can avoid this memcpy.
-  char* dst =
-      reinterpret_cast<char*>(entry) + sizeof(FieldTrial::FieldTrialEntry);
-  memcpy(dst, pickle.data(), pickle.size());
+  memcpy(entry->GetPickledDataPtr(), pickle.data(), pickle.size());
 
   allocator->MakeIterable(ref);
   field_trial->ref_ = ref;
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 3429519..b20ffd40 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -170,6 +170,12 @@
     // Expected size for 32/64-bit check.
     static constexpr size_t kExpectedInstanceSize = 16;
 
+    // Return a pointer to the data area immediately following the entry.
+    char* GetPickledDataPtr() { return reinterpret_cast<char*>(this + 1); }
+    const char* GetPickledDataPtr() const {
+      return reinterpret_cast<const char*>(this + 1);
+    }
+
     // Whether or not this field trial is activated. This is really just a
     // boolean but using a 32 bit value for portability reasons. It should be
     // accessed via NoBarrier_Load()/NoBarrier_Store() to prevent the compiler