Reland "[Sampling profiler] Provide unwinder in stack_unwinder DFM"

This is a reland of 01b9624c25a61b61bd162515f7f6cdf4569aeb2a

This is now safe to reland with the fix in https://crrev.com/772300.

Original change's description:
> [Sampling profiler] Provide unwinder in stack_unwinder DFM
>
> Implements the Android native/Java stack unwinder within the stack_unwinder
> dynamic feature module.
>
> Adds visibility/assert_no_deps constraints to //base/BUILD.gn to avoid
> leaking module implementation types into general Chrome code, which
> would defeat the purpose of using the module to avoid Chrome binary size
> increase.
>
> Adds required stub declarations/implementation for MemoryRegionsMap.
>
> Bug: 1083530, 1004855
> Change-Id: If9d31c4e1b9d214bb0baabe3afa8475ba7adef4a
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2209297
> Commit-Queue: kylechar <kylechar@chromium.org>
> Reviewed-by: kylechar <kylechar@chromium.org>
> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
> Auto-Submit: Mike Wittman <wittman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#771018}

TBR=etiennep@chromium.org,kylechar@chromium.org

Bug: 1083530, 1004855
Change-Id: I7c889d39cd7ae08c2dec9128a31742c2ff9525f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218669
Reviewed-by: Mike Wittman <wittman@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Reviewed-by: kylechar <kylechar@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772357}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index cb55cbe..9a38ec3 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1315,6 +1315,10 @@
     "//third_party/modp_b64",
   ]
 
+  # native_unwinder_android is intended for use solely via a dynamic feature
+  # module, to avoid increasing Chrome's executable size.
+  assert_no_deps = [ ":native_unwinder_android" ]
+
   public_deps = [
     ":anchor_functions_buildflags",
     ":base_static",
@@ -2424,8 +2428,16 @@
   }
 }
 
-if (is_android && (current_cpu == "arm" || current_cpu == "arm64")) {
+if (is_android) {
   source_set("native_unwinder_android") {
+    # This target is intended to be used only within the stack_unwinder dynamic
+    # feature module, to avoid binary size increase in Chrome due to the
+    # libunwindstack dependency. The additional :* visibility is needed to allow
+    # use by base test targets.
+    visibility = [
+      ":*",
+      "//chrome/android/modules/stack_unwinder/internal:*",
+    ]
     sources = [
       "profiler/native_unwinder_android.cc",
       "profiler/native_unwinder_android.h",
diff --git a/chrome/android/features/stack_unwinder/public/BUILD.gn b/chrome/android/features/stack_unwinder/public/BUILD.gn
index 5710847..74167954 100644
--- a/chrome/android/features/stack_unwinder/public/BUILD.gn
+++ b/chrome/android/features/stack_unwinder/public/BUILD.gn
@@ -4,4 +4,5 @@
 
 source_set("memory_regions_map") {
   public = [ "memory_regions_map.h" ]
+  sources = [ "memory_regions_map.cc" ]
 }
diff --git a/chrome/android/features/stack_unwinder/public/memory_regions_map.cc b/chrome/android/features/stack_unwinder/public/memory_regions_map.cc
new file mode 100644
index 0000000..4609ea7
--- /dev/null
+++ b/chrome/android/features/stack_unwinder/public/memory_regions_map.cc
@@ -0,0 +1,12 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/android/features/stack_unwinder/public/memory_regions_map.h"
+
+namespace stack_unwinder {
+
+MemoryRegionsMap::MemoryRegionsMap() = default;
+MemoryRegionsMap::~MemoryRegionsMap() = default;
+
+}  // namespace stack_unwinder
diff --git a/chrome/android/features/stack_unwinder/public/memory_regions_map.h b/chrome/android/features/stack_unwinder/public/memory_regions_map.h
index f5b3239..4a1f2aa 100644
--- a/chrome/android/features/stack_unwinder/public/memory_regions_map.h
+++ b/chrome/android/features/stack_unwinder/public/memory_regions_map.h
@@ -11,7 +11,11 @@
 // It must only be subclassed within the module implementation.
 class MemoryRegionsMap {
  public:
+  MemoryRegionsMap();
   virtual ~MemoryRegionsMap() = 0;
+
+  MemoryRegionsMap(const MemoryRegionsMap&) = delete;
+  MemoryRegionsMap& operator=(const MemoryRegionsMap&) = delete;
 };
 
 }  // namespace stack_unwinder
diff --git a/chrome/android/modules/stack_unwinder/internal/BUILD.gn b/chrome/android/modules/stack_unwinder/internal/BUILD.gn
index 23ae81de..7df6228 100644
--- a/chrome/android/modules/stack_unwinder/internal/BUILD.gn
+++ b/chrome/android/modules/stack_unwinder/internal/BUILD.gn
@@ -43,6 +43,7 @@
     ":jni_headers",
     ":jni_registration",
     "//base",
+    "//base:native_unwinder_android",
     "//chrome/android/features/stack_unwinder/public:memory_regions_map",
   ]
 
diff --git a/chrome/android/modules/stack_unwinder/internal/stack_unwinder_module_contents_impl.cc b/chrome/android/modules/stack_unwinder/internal/stack_unwinder_module_contents_impl.cc
index 0175c3c..1c7972ec 100644
--- a/chrome/android/modules/stack_unwinder/internal/stack_unwinder_module_contents_impl.cc
+++ b/chrome/android/modules/stack_unwinder/internal/stack_unwinder_module_contents_impl.cc
@@ -3,20 +3,47 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <utility>
 
-#include "base/profiler/unwinder.h"
+#include "base/profiler/native_unwinder_android.h"
 #include "chrome/android/features/stack_unwinder/public/memory_regions_map.h"
 #include "chrome/android/modules/stack_unwinder/internal/jni_headers/StackUnwinderModuleContentsImpl_jni.h"
 
+namespace {
+
+class MemoryRegionsMap : public stack_unwinder::MemoryRegionsMap {
+ public:
+  MemoryRegionsMap(std::unique_ptr<unwindstack::Maps> maps,
+                   std::unique_ptr<unwindstack::Memory> memory)
+      : maps_(std::move(maps)), memory_(std::move(memory)) {}
+
+  unwindstack::Maps* maps() { return maps_.get(); }
+  unwindstack::Memory* memory() { return memory_.get(); }
+
+ private:
+  std::unique_ptr<unwindstack::Maps> maps_;
+  std::unique_ptr<unwindstack::Memory> memory_;
+};
+
+}  // namespace
+
 std::unique_ptr<stack_unwinder::MemoryRegionsMap> CreateMemoryRegionsMap() {
-  // TODO(etiennep): Implement.
-  return nullptr;
+  return std::make_unique<MemoryRegionsMap>(
+      base::NativeUnwinderAndroid::CreateMaps(),
+      base::NativeUnwinderAndroid::CreateProcessMemory());
 }
 
 std::unique_ptr<base::Unwinder> CreateNativeUnwinder(
     stack_unwinder::MemoryRegionsMap* memory_regions_map) {
-  // TODO(etiennep): Implement.
-  return nullptr;
+  // The user is expected to only pass the subclass generated by
+  // CreateMemoryRegionsMap().
+  MemoryRegionsMap* concrete_memory_regions_map =
+      static_cast<MemoryRegionsMap*>(memory_regions_map);
+  // TODO(https://crbug.com/1004855): Provide the address of the Chrome module
+  // to as the |exclude_module_with_base_address| parameter.
+  return std::make_unique<base::NativeUnwinderAndroid>(
+      concrete_memory_regions_map->maps(),
+      concrete_memory_regions_map->memory());
 }
 
 static jlong
diff --git a/chrome/android/modules/stack_unwinder/public/BUILD.gn b/chrome/android/modules/stack_unwinder/public/BUILD.gn
index 0ea5726..b93c0c9 100644
--- a/chrome/android/modules/stack_unwinder/public/BUILD.gn
+++ b/chrome/android/modules/stack_unwinder/public/BUILD.gn
@@ -23,5 +23,4 @@
     "//chrome/android/features/stack_unwinder/public:memory_regions_map",
     "//chrome/android/modules/stack_unwinder/provider:jni_headers",
   ]
-  libs = [ "dl" ]
 }