Convert more FWL objects over to Oilpan GC.

In turn, some CFXA objects above them need to become GC'd too in
order to avoid cycles back through Persistent<>.

-- Fix some headers/IWYU to make msvc happy.

Bug: pdfium:1563
Change-Id: Ib238be056c908e96cbd04104520778740f6a9b0f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73210
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index a659d6b..ce5cc88 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -25,6 +25,7 @@
 #include "fxjs/ijs_runtime.h"
 #include "public/fpdf_formfill.h"
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
@@ -85,10 +86,15 @@
 
 CPDFXFA_Context::CPDFXFA_Context(CPDF_Document* pPDFDoc)
     : m_pPDFDoc(pPDFDoc),
-      m_pXFAApp(std::make_unique<CXFA_FFApp>(this)),
       m_pDocEnv(std::make_unique<CPDFXFA_DocEnvironment>(this)),
       m_pGCHeap(FXGC_CreateHeap()) {
   ASSERT(m_pPDFDoc);
+
+  // There might not be a heap when JS not initialized.
+  if (m_pGCHeap) {
+    m_pXFAApp = cppgc::MakeGarbageCollected<CXFA_FFApp>(
+        m_pGCHeap->GetAllocationHandle(), this);
+  }
 }
 
 CPDFXFA_Context::~CPDFXFA_Context() {
@@ -104,6 +110,9 @@
   // the layout data to clear.
   if (m_pXFADoc && m_pXFADoc->GetXFADoc()) {
     m_pXFADoc->GetXFADoc()->ClearLayoutData();
+    m_pXFADocView.Clear();
+    m_pXFADoc.Clear();
+    m_pXFAApp.Clear();
     FXGC_ForceGarbageCollection(m_pGCHeap.get());
   }
   m_pFormFillEnv.Reset(pFormFillEnv);
@@ -134,7 +143,7 @@
 
   AutoNuller<cppgc::Persistent<CXFA_FFDoc>> doc_nuller(&m_pXFADoc);
   m_pXFADoc = cppgc::MakeGarbageCollected<CXFA_FFDoc>(
-      m_pGCHeap->GetAllocationHandle(), m_pXFAApp.get(), m_pDocEnv.get(),
+      m_pGCHeap->GetAllocationHandle(), m_pXFAApp, m_pDocEnv.get(),
       m_pPDFDoc.Get(), m_pGCHeap.get());
 
   if (!m_pXFADoc->OpenDoc(m_pXML.get())) {
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index 14daddb..cb5461c 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -116,7 +116,6 @@
   // The order in which the following members are destroyed is critical.
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
   std::unique_ptr<CFX_XMLDocument> m_pXML;
-  std::unique_ptr<CXFA_FFApp> const m_pXFAApp;
   ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
   std::vector<RetainPtr<CPDFXFA_Page>> m_XFAPageList;
 
@@ -124,6 +123,7 @@
   std::unique_ptr<CPDFXFA_DocEnvironment> m_pDocEnv;
 
   FXGCScopedHeap m_pGCHeap;
+  cppgc::Persistent<CXFA_FFApp> m_pXFAApp;          // can't outlive |m_pGCHeap|
   cppgc::Persistent<CXFA_FFDoc> m_pXFADoc;          // Can't outlive |m_pGCHeap|
   cppgc::Persistent<CXFA_FFDocView> m_pXFADocView;  // Can't outlive |m_pGCHeap|
 };
diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h
index 6bc32d9..6c7df2c 100644
--- a/xfa/fgas/font/cfgas_fontmgr.h
+++ b/xfa/fgas/font/cfgas_fontmgr.h
@@ -15,11 +15,11 @@
 
 #include "build/build_config.h"
 #include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_face.h"
 #include "core/fxge/fx_freetype.h"
-#include "xfa/fgas/font/cfgas_pdffontmgr.h"
 
 class CFGAS_FontSourceEnumFile;
 class CFGAS_GEFont;
diff --git a/xfa/fgas/font/cfgas_pdffontmgr.h b/xfa/fgas/font/cfgas_pdffontmgr.h
index f9c56fc..750ff7c 100644
--- a/xfa/fgas/font/cfgas_pdffontmgr.h
+++ b/xfa/fgas/font/cfgas_pdffontmgr.h
@@ -12,14 +12,15 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/unowned_ptr.h"
+#include "xfa/fgas/font/cfgas_fontmgr.h"
 
-class CFGAS_FontMgr;
 class CFGAS_GEFont;
 class CPDF_Document;
 
 class CFGAS_PDFFontMgr final : public Observable {
  public:
-  explicit CFGAS_PDFFontMgr(CPDF_Document* pDoc, CFGAS_FontMgr* pFontMgr);
+  CFGAS_PDFFontMgr(CPDF_Document* pDoc, CFGAS_FontMgr* pFontMgr);
   ~CFGAS_PDFFontMgr();
 
   RetainPtr<CFGAS_GEFont> GetFont(WideStringView wsFontFamily,
@@ -41,7 +42,7 @@
                              bool bStrictMatch);
 
   UnownedPtr<CPDF_Document> const m_pDoc;
-  UnownedPtr<CFGAS_FontMgr> const m_pFontMgr;
+  ObservedPtr<CFGAS_FontMgr> const m_pFontMgr;
   std::map<ByteString, RetainPtr<CFGAS_GEFont>> m_FontMap;
 };
 
diff --git a/xfa/fwl/cfwl_app.cpp b/xfa/fwl/cfwl_app.cpp
index 4249732..3e8bd4f 100644
--- a/xfa/fwl/cfwl_app.cpp
+++ b/xfa/fwl/cfwl_app.cpp
@@ -6,16 +6,24 @@
 
 #include "xfa/fwl/cfwl_app.h"
 
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_widget.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 
 CFWL_App::CFWL_App(AdapterIface* pAdapter)
     : m_pAdapter(pAdapter),
-      m_pWidgetMgr(
-          std::make_unique<CFWL_WidgetMgr>(pAdapter->GetWidgetMgrAdapter())),
-      m_pNoteDriver(std::make_unique<CFWL_NoteDriver>()) {
-  ASSERT(m_pAdapter);
-}
+      m_pWidgetMgr(cppgc::MakeGarbageCollected<CFWL_WidgetMgr>(
+          pAdapter->GetHeap()->GetAllocationHandle(),
+          pAdapter->GetWidgetMgrAdapter(),
+          this)),
+      m_pNoteDriver(cppgc::MakeGarbageCollected<CFWL_NoteDriver>(
+          pAdapter->GetHeap()->GetAllocationHandle())) {}
 
 CFWL_App::~CFWL_App() = default;
+
+void CFWL_App::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pAdapter);
+  visitor->Trace(m_pWidgetMgr);
+  visitor->Trace(m_pNoteDriver);
+}
diff --git a/xfa/fwl/cfwl_app.h b/xfa/fwl/cfwl_app.h
index 918cdf1..c27aece 100644
--- a/xfa/fwl/cfwl_app.h
+++ b/xfa/fwl/cfwl_app.h
@@ -10,15 +10,15 @@
 #include <memory>
 
 #include "core/fxcrt/timerhandler_iface.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 
 class CFWL_NoteDriver;
 class IFWL_ThemeProvider;
 
-namespace cppgc {
-class Heap;
-}  // namespace cppgc
-
 enum FWL_KeyFlag {
   FWL_KEYFLAG_Ctrl = 1 << 0,
   FWL_KEYFLAG_Alt = 1 << 1,
@@ -29,9 +29,9 @@
   FWL_KEYFLAG_MButton = 1 << 6
 };
 
-class CFWL_App {
+class CFWL_App final : public cppgc::GarbageCollected<CFWL_App> {
  public:
-  class AdapterIface {
+  class AdapterIface : public cppgc::GarbageCollectedMixin {
    public:
     virtual ~AdapterIface() = default;
     virtual CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() = 0;
@@ -40,9 +40,11 @@
     virtual cppgc::Heap* GetHeap() = 0;
   };
 
-  explicit CFWL_App(AdapterIface* pAdapter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_App();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() const {
     return m_pAdapter->GetWidgetMgrAdapter();
   }
@@ -53,13 +55,15 @@
     return m_pAdapter->GetThemeProvider();
   }
   cppgc::Heap* GetHeap() const { return m_pAdapter->GetHeap(); }
-  CFWL_WidgetMgr* GetWidgetMgr() const { return m_pWidgetMgr.get(); }
-  CFWL_NoteDriver* GetNoteDriver() const { return m_pNoteDriver.get(); }
+  CFWL_WidgetMgr* GetWidgetMgr() const { return m_pWidgetMgr; }
+  CFWL_NoteDriver* GetNoteDriver() const { return m_pNoteDriver; }
 
  private:
-  UnownedPtr<AdapterIface> const m_pAdapter;
-  std::unique_ptr<CFWL_WidgetMgr> m_pWidgetMgr;
-  std::unique_ptr<CFWL_NoteDriver> m_pNoteDriver;
+  explicit CFWL_App(AdapterIface* pAdapter);
+
+  cppgc::Member<AdapterIface> const m_pAdapter;
+  cppgc::Member<CFWL_WidgetMgr> m_pWidgetMgr;
+  cppgc::Member<CFWL_NoteDriver> m_pNoteDriver;
 };
 
 #endif  // XFA_FWL_CFWL_APP_H_
diff --git a/xfa/fwl/cfwl_barcode.cpp b/xfa/fwl/cfwl_barcode.cpp
index 08233c2..c43d741 100644
--- a/xfa/fwl/cfwl_barcode.cpp
+++ b/xfa/fwl/cfwl_barcode.cpp
@@ -15,7 +15,7 @@
 #include "xfa/fwl/ifwl_themeprovider.h"
 #include "xfa/fwl/theme/cfwl_utils.h"
 
-CFWL_Barcode::CFWL_Barcode(const CFWL_App* app)
+CFWL_Barcode::CFWL_Barcode(CFWL_App* app)
     : CFWL_Edit(app, Properties(), nullptr) {}
 
 CFWL_Barcode::~CFWL_Barcode() = default;
diff --git a/xfa/fwl/cfwl_barcode.h b/xfa/fwl/cfwl_barcode.h
index 5f3c4c4..0af87fd 100644
--- a/xfa/fwl/cfwl_barcode.h
+++ b/xfa/fwl/cfwl_barcode.h
@@ -66,7 +66,7 @@
     kEncodeSuccess,
   };
 
-  explicit CFWL_Barcode(const CFWL_App* pApp);
+  explicit CFWL_Barcode(CFWL_App* pApp);
 
   void GenerateBarcodeImageCache();
   void CreateBarcodeEngine();
diff --git a/xfa/fwl/cfwl_caret.cpp b/xfa/fwl/cfwl_caret.cpp
index f705e1a..589046a 100644
--- a/xfa/fwl/cfwl_caret.cpp
+++ b/xfa/fwl/cfwl_caret.cpp
@@ -22,7 +22,7 @@
 
 }  // namespace
 
-CFWL_Caret::CFWL_Caret(const CFWL_App* app,
+CFWL_Caret::CFWL_Caret(CFWL_App* app,
                        const Properties& properties,
                        CFWL_Widget* pOuter)
     : CFWL_Widget(app, properties, pOuter) {
diff --git a/xfa/fwl/cfwl_caret.h b/xfa/fwl/cfwl_caret.h
index 8eae25d..a4dac04 100644
--- a/xfa/fwl/cfwl_caret.h
+++ b/xfa/fwl/cfwl_caret.h
@@ -33,9 +33,7 @@
   void HideCaret();
 
  private:
-  CFWL_Caret(const CFWL_App* app,
-             const Properties& properties,
-             CFWL_Widget* pOuter);
+  CFWL_Caret(CFWL_App* app, const Properties& properties, CFWL_Widget* pOuter);
 
   void DrawCaretBK(CXFA_Graphics* pGraphics, const CFX_Matrix* pMatrix);
 
diff --git a/xfa/fwl/cfwl_checkbox.cpp b/xfa/fwl/cfwl_checkbox.cpp
index 6bd420d..bb7dc57 100644
--- a/xfa/fwl/cfwl_checkbox.cpp
+++ b/xfa/fwl/cfwl_checkbox.cpp
@@ -27,7 +27,7 @@
 
 }  // namespace
 
-CFWL_CheckBox::CFWL_CheckBox(const CFWL_App* app)
+CFWL_CheckBox::CFWL_CheckBox(CFWL_App* app)
     : CFWL_Widget(app, Properties(), nullptr) {
   m_TTOStyles.single_line_ = true;
 }
diff --git a/xfa/fwl/cfwl_checkbox.h b/xfa/fwl/cfwl_checkbox.h
index 4f417dd..46f4bfe 100644
--- a/xfa/fwl/cfwl_checkbox.h
+++ b/xfa/fwl/cfwl_checkbox.h
@@ -45,7 +45,7 @@
   void SetBoxSize(float fHeight);
 
  private:
-  explicit CFWL_CheckBox(const CFWL_App* pApp);
+  explicit CFWL_CheckBox(CFWL_App* pApp);
 
   void SetCheckState(int32_t iCheck);
   void Layout();
diff --git a/xfa/fwl/cfwl_combobox.cpp b/xfa/fwl/cfwl_combobox.cpp
index 450368d..72ee145 100644
--- a/xfa/fwl/cfwl_combobox.cpp
+++ b/xfa/fwl/cfwl_combobox.cpp
@@ -28,7 +28,7 @@
 #include "xfa/fwl/fwl_widgetdef.h"
 #include "xfa/fwl/ifwl_themeprovider.h"
 
-CFWL_ComboBox::CFWL_ComboBox(const CFWL_App* app)
+CFWL_ComboBox::CFWL_ComboBox(CFWL_App* app)
     : CFWL_Widget(app, Properties(), nullptr),
       m_pEdit(cppgc::MakeGarbageCollected<CFWL_ComboEdit>(
           app->GetHeap()->GetAllocationHandle(),
diff --git a/xfa/fwl/cfwl_combobox.h b/xfa/fwl/cfwl_combobox.h
index aa8d35e..a849d1c 100644
--- a/xfa/fwl/cfwl_combobox.h
+++ b/xfa/fwl/cfwl_combobox.h
@@ -93,7 +93,7 @@
   int32_t GetCurrentSelection() const { return m_iCurSel; }
 
  private:
-  explicit CFWL_ComboBox(const CFWL_App* pApp);
+  explicit CFWL_ComboBox(CFWL_App* pApp);
 
   bool IsDropDownStyle() const {
     return !!(m_Properties.m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown);
diff --git a/xfa/fwl/cfwl_comboedit.cpp b/xfa/fwl/cfwl_comboedit.cpp
index cad3231..09fb70f 100644
--- a/xfa/fwl/cfwl_comboedit.cpp
+++ b/xfa/fwl/cfwl_comboedit.cpp
@@ -12,7 +12,7 @@
 #include "xfa/fwl/cfwl_combobox.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
 
-CFWL_ComboEdit::CFWL_ComboEdit(const CFWL_App* app,
+CFWL_ComboEdit::CFWL_ComboEdit(CFWL_App* app,
                                const Properties& properties,
                                CFWL_Widget* pOuter)
     : CFWL_Edit(app, properties, pOuter) {}
diff --git a/xfa/fwl/cfwl_comboedit.h b/xfa/fwl/cfwl_comboedit.h
index 8eb6712..23251b2 100644
--- a/xfa/fwl/cfwl_comboedit.h
+++ b/xfa/fwl/cfwl_comboedit.h
@@ -23,7 +23,7 @@
   void FlagFocus(bool bSet);
 
  private:
-  CFWL_ComboEdit(const CFWL_App* app,
+  CFWL_ComboEdit(CFWL_App* app,
                  const Properties& properties,
                  CFWL_Widget* pOuter);
 };
diff --git a/xfa/fwl/cfwl_combolist.cpp b/xfa/fwl/cfwl_combolist.cpp
index c7b59bd..846719f 100644
--- a/xfa/fwl/cfwl_combolist.cpp
+++ b/xfa/fwl/cfwl_combolist.cpp
@@ -16,7 +16,7 @@
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/fwl_widgetdef.h"
 
-CFWL_ComboList::CFWL_ComboList(const CFWL_App* app,
+CFWL_ComboList::CFWL_ComboList(CFWL_App* app,
                                const Properties& properties,
                                CFWL_Widget* pOuter)
     : CFWL_ListBox(app, properties, pOuter) {
diff --git a/xfa/fwl/cfwl_combolist.h b/xfa/fwl/cfwl_combolist.h
index 550a44b..f74dcd3 100644
--- a/xfa/fwl/cfwl_combolist.h
+++ b/xfa/fwl/cfwl_combolist.h
@@ -23,7 +23,7 @@
   void SetNotifyOwner(bool notify) { m_bNotifyOwner = notify; }
 
  private:
-  CFWL_ComboList(const CFWL_App* app,
+  CFWL_ComboList(CFWL_App* app,
                  const Properties& properties,
                  CFWL_Widget* pOuter);
 
diff --git a/xfa/fwl/cfwl_datetimeedit.cpp b/xfa/fwl/cfwl_datetimeedit.cpp
index bb6c12e..736c827 100644
--- a/xfa/fwl/cfwl_datetimeedit.cpp
+++ b/xfa/fwl/cfwl_datetimeedit.cpp
@@ -12,7 +12,7 @@
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 
-CFWL_DateTimeEdit::CFWL_DateTimeEdit(const CFWL_App* app,
+CFWL_DateTimeEdit::CFWL_DateTimeEdit(CFWL_App* app,
                                      const Properties& properties,
                                      CFWL_Widget* pOuter)
     : CFWL_Edit(app, properties, pOuter) {}
diff --git a/xfa/fwl/cfwl_datetimeedit.h b/xfa/fwl/cfwl_datetimeedit.h
index c89635e..88200fc 100644
--- a/xfa/fwl/cfwl_datetimeedit.h
+++ b/xfa/fwl/cfwl_datetimeedit.h
@@ -19,7 +19,7 @@
   void OnProcessMessage(CFWL_Message* pMessage) override;
 
  private:
-  CFWL_DateTimeEdit(const CFWL_App* app,
+  CFWL_DateTimeEdit(CFWL_App* app,
                     const Properties& properties,
                     CFWL_Widget* pOuter);
 };
diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp
index 3418f41..c9f001e 100644
--- a/xfa/fwl/cfwl_datetimepicker.cpp
+++ b/xfa/fwl/cfwl_datetimepicker.cpp
@@ -8,7 +8,6 @@
 
 #include <utility>
 
-#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_event.h"
 #include "xfa/fwl/cfwl_eventselectchanged.h"
@@ -24,7 +23,7 @@
 const int kDateTimePickerHeight = 20;
 
 }  // namespace
-CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app)
+CFWL_DateTimePicker::CFWL_DateTimePicker(CFWL_App* app)
     : CFWL_Widget(app,
                   Properties{0, FWL_STYLEEXT_DTP_ShortDateFormat, 0},
                   nullptr),
@@ -149,11 +148,7 @@
   if (!m_pEdit)
     return;
 
-  ObservedPtr<CFWL_DateTimePicker> watched(this);
-  m_pEdit->SetText(wsText);  // JS may destroy |this|.
-  if (!watched)
-    return;
-
+  m_pEdit->SetText(wsText);
   RepaintRect(m_ClientRect);
 
   CFWL_Event ev(CFWL_Event::Type::EditChanged);
@@ -294,13 +289,7 @@
   m_iYear = iYear;
   m_iMonth = iMonth;
   m_iDay = iDay;
-
-  ObservedPtr<CFWL_DateTimePicker> watched(this);
-  WideString wsText = FormatDateString(m_iYear, m_iMonth, m_iDay);
-  m_pEdit->SetText(wsText);  // JS may destroy |this|.
-  if (!watched)
-    return;
-
+  m_pEdit->SetText(FormatDateString(m_iYear, m_iMonth, m_iDay));
   m_pEdit->Update();
   RepaintRect(m_ClientRect);
 
diff --git a/xfa/fwl/cfwl_datetimepicker.h b/xfa/fwl/cfwl_datetimepicker.h
index e2263f7..50a40ed 100644
--- a/xfa/fwl/cfwl_datetimepicker.h
+++ b/xfa/fwl/cfwl_datetimepicker.h
@@ -76,7 +76,7 @@
   void ProcessSelChanged(int32_t iYear, int32_t iMonth, int32_t iDay);
 
  private:
-  explicit CFWL_DateTimePicker(const CFWL_App* pApp);
+  explicit CFWL_DateTimePicker(CFWL_App* pApp);
 
   void DrawDropDownButton(CXFA_Graphics* pGraphics, const CFX_Matrix* pMatrix);
   WideString FormatDateString(int32_t iYear, int32_t iMonth, int32_t iDay);
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index f19b1fc..969c27b 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -45,7 +45,7 @@
 
 }  // namespace
 
-CFWL_Edit::CFWL_Edit(const CFWL_App* app,
+CFWL_Edit::CFWL_Edit(CFWL_App* app,
                      const Properties& properties,
                      CFWL_Widget* pOuter)
     : CFWL_Widget(app, properties, pOuter),
diff --git a/xfa/fwl/cfwl_edit.h b/xfa/fwl/cfwl_edit.h
index 078ef34..e123a0f 100644
--- a/xfa/fwl/cfwl_edit.h
+++ b/xfa/fwl/cfwl_edit.h
@@ -96,9 +96,7 @@
   void SetScrollOffset(float fScrollOffset) override;
 
  protected:
-  CFWL_Edit(const CFWL_App* app,
-            const Properties& properties,
-            CFWL_Widget* pOuter);
+  CFWL_Edit(CFWL_App* app, const Properties& properties, CFWL_Widget* pOuter);
 
   void ShowCaret(CFX_RectF* pRect);
   void HideCaret(CFX_RectF* pRect);
diff --git a/xfa/fwl/cfwl_listbox.cpp b/xfa/fwl/cfwl_listbox.cpp
index a52c7d7..b4eaac2 100644
--- a/xfa/fwl/cfwl_listbox.cpp
+++ b/xfa/fwl/cfwl_listbox.cpp
@@ -29,7 +29,7 @@
 
 }  // namespace
 
-CFWL_ListBox::CFWL_ListBox(const CFWL_App* app,
+CFWL_ListBox::CFWL_ListBox(CFWL_App* app,
                            const Properties& properties,
                            CFWL_Widget* pOuter)
     : CFWL_Widget(app, properties, pOuter) {}
diff --git a/xfa/fwl/cfwl_listbox.h b/xfa/fwl/cfwl_listbox.h
index 28e2b06..1443246 100644
--- a/xfa/fwl/cfwl_listbox.h
+++ b/xfa/fwl/cfwl_listbox.h
@@ -77,7 +77,7 @@
   float CalcItemHeight();
 
  protected:
-  CFWL_ListBox(const CFWL_App* pApp,
+  CFWL_ListBox(CFWL_App* pApp,
                const Properties& properties,
                CFWL_Widget* pOuter);
 
diff --git a/xfa/fwl/cfwl_monthcalendar.cpp b/xfa/fwl/cfwl_monthcalendar.cpp
index 5af4080..0943675 100644
--- a/xfa/fwl/cfwl_monthcalendar.cpp
+++ b/xfa/fwl/cfwl_monthcalendar.cpp
@@ -85,7 +85,7 @@
 
 }  // namespace
 
-CFWL_MonthCalendar::CFWL_MonthCalendar(const CFWL_App* app,
+CFWL_MonthCalendar::CFWL_MonthCalendar(CFWL_App* app,
                                        const Properties& properties,
                                        CFWL_Widget* pOuter)
     : CFWL_Widget(app, properties, pOuter) {}
diff --git a/xfa/fwl/cfwl_monthcalendar.h b/xfa/fwl/cfwl_monthcalendar.h
index 83afae8..b23217d 100644
--- a/xfa/fwl/cfwl_monthcalendar.h
+++ b/xfa/fwl/cfwl_monthcalendar.h
@@ -85,7 +85,7 @@
     WideString wsDay;
   };
 
-  CFWL_MonthCalendar(const CFWL_App* app,
+  CFWL_MonthCalendar(CFWL_App* app,
                      const Properties& properties,
                      CFWL_Widget* pOuter);
 
diff --git a/xfa/fwl/cfwl_notedriver.cpp b/xfa/fwl/cfwl_notedriver.cpp
index 897ef85..8b42e1a 100644
--- a/xfa/fwl/cfwl_notedriver.cpp
+++ b/xfa/fwl/cfwl_notedriver.cpp
@@ -13,6 +13,7 @@
 #include "core/fxcrt/fx_extension.h"
 #include "third_party/base/stl_util.h"
 #include "xfa/fwl/cfwl_app.h"
+#include "xfa/fwl/cfwl_event.h"
 #include "xfa/fwl/cfwl_messagekey.h"
 #include "xfa/fwl/cfwl_messagekillfocus.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
@@ -31,6 +32,15 @@
 
 CFWL_NoteDriver::~CFWL_NoteDriver() = default;
 
+void CFWL_NoteDriver::Trace(cppgc::Visitor* visitor) const {
+  for (const auto& item : m_eventTargets)
+    item.second->Trace(visitor);
+
+  visitor->Trace(m_pHover);
+  visitor->Trace(m_pFocus);
+  visitor->Trace(m_pGrab);
+}
+
 void CFWL_NoteDriver::SendEvent(CFWL_Event* pNote) {
   for (const auto& pair : m_eventTargets) {
     if (pair.second->IsValid())
@@ -244,6 +254,12 @@
 
 CFWL_NoteDriver::Target::~Target() = default;
 
+void CFWL_NoteDriver::Target::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pListener);
+  for (auto& widget : m_widgets)
+    visitor->Trace(widget);
+}
+
 void CFWL_NoteDriver::Target::SetEventSource(CFWL_Widget* pSource) {
   if (pSource)
     m_widgets.insert(pSource);
diff --git a/xfa/fwl/cfwl_notedriver.h b/xfa/fwl/cfwl_notedriver.h
index 92554c2..2fe2360 100644
--- a/xfa/fwl/cfwl_notedriver.h
+++ b/xfa/fwl/cfwl_notedriver.h
@@ -9,19 +9,24 @@
 
 #include <map>
 #include <memory>
+#include <set>
 
-#include "core/fxcrt/unowned_ptr.h"
-#include "xfa/fwl/cfwl_event.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_widget.h"
 #include "xfa/fxgraphics/cxfa_graphics.h"
 
 class CFWL_Event;
 
-class CFWL_NoteDriver {
+class CFWL_NoteDriver final : public cppgc::GarbageCollected<CFWL_NoteDriver> {
  public:
-  CFWL_NoteDriver();
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_NoteDriver();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   void SendEvent(CFWL_Event* pNote);
   void ProcessMessage(CFWL_Message* pMessage);
   void RegisterEventTarget(CFWL_Widget* pListener, CFWL_Widget* pEventSource);
@@ -36,6 +41,7 @@
     explicit Target(CFWL_Widget* pListener);
     ~Target();
 
+    void Trace(cppgc::Visitor* visitor) const;
     void SetEventSource(CFWL_Widget* pSource);
     bool ProcessEvent(CFWL_Event* pEvent);
     bool IsValid() const { return m_bValid; }
@@ -43,10 +49,12 @@
 
    private:
     bool m_bValid = true;
-    CFWL_Widget* const m_pListener;
-    std::set<CFWL_Widget*> m_widgets;
+    cppgc::Member<CFWL_Widget> const m_pListener;
+    std::set<cppgc::Member<CFWL_Widget>> m_widgets;
   };
 
+  CFWL_NoteDriver();
+
   bool DispatchMessage(CFWL_Message* pMessage, CFWL_Widget* pMessageForm);
   bool DoSetFocus(CFWL_Message* pMsg, CFWL_Widget* pMessageForm);
   bool DoKillFocus(CFWL_Message* pMsg, CFWL_Widget* pMessageForm);
@@ -57,9 +65,9 @@
   void MouseSecondary(CFWL_Message* pMsg);
 
   std::map<uint64_t, std::unique_ptr<Target>> m_eventTargets;
-  UnownedPtr<CFWL_Widget> m_pHover;
-  UnownedPtr<CFWL_Widget> m_pFocus;
-  UnownedPtr<CFWL_Widget> m_pGrab;
+  cppgc::Member<CFWL_Widget> m_pHover;
+  cppgc::Member<CFWL_Widget> m_pFocus;
+  cppgc::Member<CFWL_Widget> m_pGrab;
 };
 
 #endif  // XFA_FWL_CFWL_NOTEDRIVER_H_
diff --git a/xfa/fwl/cfwl_picturebox.cpp b/xfa/fwl/cfwl_picturebox.cpp
index fafa67e..9532ceb 100644
--- a/xfa/fwl/cfwl_picturebox.cpp
+++ b/xfa/fwl/cfwl_picturebox.cpp
@@ -6,7 +6,7 @@
 
 #include "xfa/fwl/cfwl_picturebox.h"
 
-CFWL_PictureBox::CFWL_PictureBox(const CFWL_App* app)
+CFWL_PictureBox::CFWL_PictureBox(CFWL_App* app)
     : CFWL_Widget(app, CFWL_Widget::Properties(), nullptr) {}
 
 CFWL_PictureBox::~CFWL_PictureBox() = default;
diff --git a/xfa/fwl/cfwl_picturebox.h b/xfa/fwl/cfwl_picturebox.h
index 7ede805..43f1c7a 100644
--- a/xfa/fwl/cfwl_picturebox.h
+++ b/xfa/fwl/cfwl_picturebox.h
@@ -25,7 +25,7 @@
                     const CFX_Matrix& matrix) override;
 
  private:
-  explicit CFWL_PictureBox(const CFWL_App* pApp);
+  explicit CFWL_PictureBox(CFWL_App* pApp);
 
   CFX_RectF m_ClientRect;
   CFX_RectF m_ImageRect;
diff --git a/xfa/fwl/cfwl_pushbutton.cpp b/xfa/fwl/cfwl_pushbutton.cpp
index d0764d8..ed608af 100644
--- a/xfa/fwl/cfwl_pushbutton.cpp
+++ b/xfa/fwl/cfwl_pushbutton.cpp
@@ -19,7 +19,7 @@
 #include "xfa/fwl/fwl_widgetdef.h"
 #include "xfa/fwl/ifwl_themeprovider.h"
 
-CFWL_PushButton::CFWL_PushButton(const CFWL_App* app)
+CFWL_PushButton::CFWL_PushButton(CFWL_App* app)
     : CFWL_Widget(app, Properties(), nullptr) {}
 
 CFWL_PushButton::~CFWL_PushButton() = default;
diff --git a/xfa/fwl/cfwl_pushbutton.h b/xfa/fwl/cfwl_pushbutton.h
index efd5412..07de454 100644
--- a/xfa/fwl/cfwl_pushbutton.h
+++ b/xfa/fwl/cfwl_pushbutton.h
@@ -31,7 +31,7 @@
                     const CFX_Matrix& matrix) override;
 
  private:
-  explicit CFWL_PushButton(const CFWL_App*);
+  explicit CFWL_PushButton(CFWL_App* pApp);
 
   void DrawBkground(CXFA_Graphics* pGraphics,
                     const CFX_Matrix* pMatrix);
diff --git a/xfa/fwl/cfwl_scrollbar.cpp b/xfa/fwl/cfwl_scrollbar.cpp
index 7ba20cd..5bfb988 100644
--- a/xfa/fwl/cfwl_scrollbar.cpp
+++ b/xfa/fwl/cfwl_scrollbar.cpp
@@ -27,7 +27,7 @@
 
 }  // namespace
 
-CFWL_ScrollBar::CFWL_ScrollBar(const CFWL_App* app,
+CFWL_ScrollBar::CFWL_ScrollBar(CFWL_App* app,
                                const Properties& properties,
                                CFWL_Widget* pOuter)
     : CFWL_Widget(app, properties, pOuter) {}
diff --git a/xfa/fwl/cfwl_scrollbar.h b/xfa/fwl/cfwl_scrollbar.h
index 4cacfc9..aef61a3 100644
--- a/xfa/fwl/cfwl_scrollbar.h
+++ b/xfa/fwl/cfwl_scrollbar.h
@@ -53,7 +53,7 @@
   void SetTrackPos(float fTrackPos);
 
  private:
-  CFWL_ScrollBar(const CFWL_App* app,
+  CFWL_ScrollBar(CFWL_App* app,
                  const Properties& properties,
                  CFWL_Widget* pOuter);
 
diff --git a/xfa/fwl/cfwl_widget.cpp b/xfa/fwl/cfwl_widget.cpp
index 8b5aafe..739b90e 100644
--- a/xfa/fwl/cfwl_widget.cpp
+++ b/xfa/fwl/cfwl_widget.cpp
@@ -33,7 +33,7 @@
 #define FWL_WGT_CalcWidth 2048
 #define FWL_WGT_CalcMultiLineDefWidth 120.0f
 
-CFWL_Widget::CFWL_Widget(const CFWL_App* app,
+CFWL_Widget::CFWL_Widget(CFWL_App* app,
                          const Properties& properties,
                          CFWL_Widget* pOuter)
     : m_Properties(properties),
@@ -52,8 +52,10 @@
 }
 
 void CFWL_Widget::Trace(cppgc::Visitor* visitor) const {
-  visitor->Trace(m_pOuter);
+  visitor->Trace(m_pFWLApp);
+  visitor->Trace(m_pWidgetMgr);
   visitor->Trace(m_pDelegate);
+  visitor->Trace(m_pOuter);
 }
 
 bool CFWL_Widget::IsForm() const {
diff --git a/xfa/fwl/cfwl_widget.h b/xfa/fwl/cfwl_widget.h
index f419ac2..6507632 100644
--- a/xfa/fwl/cfwl_widget.h
+++ b/xfa/fwl/cfwl_widget.h
@@ -9,7 +9,6 @@
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/gc/heap.h"
 #include "v8/include/cppgc/garbage-collected.h"
@@ -53,7 +52,6 @@
 
 // NOTE: CFWL_Widget serves as its own delegate until replaced at runtime.
 class CFWL_Widget : public cppgc::GarbageCollected<CFWL_Widget>,
-                    public Observable,
                     public IFWL_WidgetDelegate {
   CPPGC_USING_PRE_FINALIZER(CFWL_Widget, PreFinalize);
 
@@ -118,7 +116,7 @@
   bool IsPopup() const;
   bool IsChild() const;
 
-  CFWL_WidgetMgr* GetWidgetMgr() const { return m_pWidgetMgr.Get(); }
+  CFWL_WidgetMgr* GetWidgetMgr() const { return m_pWidgetMgr; }
   CFWL_Widget* GetOuter() const { return m_pOuter; }
   CFWL_Widget* GetOutmost() const;
 
@@ -137,7 +135,7 @@
     return m_pDelegate ? m_pDelegate.Get() : this;
   }
 
-  const CFWL_App* GetFWLApp() const { return m_pFWLApp.Get(); }
+  CFWL_App* GetFWLApp() const { return m_pFWLApp.Get(); }
   uint64_t GetEventKey() const { return m_nEventKey; }
   void SetEventKey(uint64_t key) { m_nEventKey = key; }
 
@@ -146,9 +144,7 @@
   void RepaintRect(const CFX_RectF& pRect);
 
  protected:
-  CFWL_Widget(const CFWL_App* app,
-              const Properties& properties,
-              CFWL_Widget* pOuter);
+  CFWL_Widget(CFWL_App* app, const Properties& properties, CFWL_Widget* pOuter);
 
   bool IsEnabled() const;
   bool IsLocked() const { return m_iLock > 0; }
@@ -191,11 +187,11 @@
 
   int32_t m_iLock = 0;
   uint64_t m_nEventKey = 0;
-  UnownedPtr<const CFWL_App> const m_pFWLApp;
-  UnownedPtr<CFWL_WidgetMgr> const m_pWidgetMgr;
-  cppgc::Member<CFWL_Widget> const m_pOuter;
   AdapterIface* m_pAdapterIface = nullptr;
+  cppgc::Member<CFWL_App> const m_pFWLApp;
+  cppgc::Member<CFWL_WidgetMgr> const m_pWidgetMgr;
   cppgc::Member<IFWL_WidgetDelegate> m_pDelegate;
+  cppgc::Member<CFWL_Widget> const m_pOuter;
 };
 
 #endif  // XFA_FWL_CFWL_WIDGET_H_
diff --git a/xfa/fwl/cfwl_widgetmgr.cpp b/xfa/fwl/cfwl_widgetmgr.cpp
index 5a33f34..d52a1fa 100644
--- a/xfa/fwl/cfwl_widgetmgr.cpp
+++ b/xfa/fwl/cfwl_widgetmgr.cpp
@@ -13,13 +13,22 @@
 #include "xfa/fwl/cfwl_message.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 
-CFWL_WidgetMgr::CFWL_WidgetMgr(AdapterIface* pAdapterNative)
-    : m_pAdapter(pAdapterNative) {
-  m_mapWidgetItem[nullptr] = std::make_unique<Item>();
+CFWL_WidgetMgr::CFWL_WidgetMgr(AdapterIface* pAdapter, CFWL_App* pApp)
+    : m_pAdapter(pAdapter), m_pApp(pApp) {
+  ASSERT(m_pAdapter);
+  m_mapWidgetItem[nullptr] = cppgc::MakeGarbageCollected<Item>(
+      pApp->GetHeap()->GetAllocationHandle(), nullptr);
 }
 
 CFWL_WidgetMgr::~CFWL_WidgetMgr() = default;
 
+void CFWL_WidgetMgr::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pApp);
+  visitor->Trace(m_pAdapter);
+  for (auto& item : m_mapWidgetItem)
+    visitor->Trace(item.second);
+}
+
 CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(const CFWL_Widget* pWidget) const {
   Item* pItem = GetWidgetMgrItem(pWidget);
   if (!pItem)
@@ -152,14 +161,14 @@
 CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
     const CFWL_Widget* pWidget) const {
   auto it = m_mapWidgetItem.find(pWidget);
-  return it != m_mapWidgetItem.end() ? it->second.get() : nullptr;
+  return it != m_mapWidgetItem.end() ? it->second : nullptr;
 }
 
 CFWL_WidgetMgr::Item* CFWL_WidgetMgr::CreateWidgetMgrItem(
     CFWL_Widget* pWidget) {
-  auto pOwnedItem = std::make_unique<Item>(pWidget);
-  auto* pItem = pOwnedItem.get();
-  m_mapWidgetItem[pWidget] = std::move(pOwnedItem);
+  auto* pItem = cppgc::MakeGarbageCollected<Item>(
+      m_pApp->GetHeap()->GetAllocationHandle(), pWidget);
+  m_mapWidgetItem[pWidget] = pItem;
   return pItem;
 }
 
@@ -226,8 +235,11 @@
   }
 }
 
-CFWL_WidgetMgr::Item::Item() : pWidget(nullptr) {}
-
 CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) : pWidget(widget) {}
 
 CFWL_WidgetMgr::Item::~Item() = default;
+
+void CFWL_WidgetMgr::Item::Trace(cppgc::Visitor* visitor) const {
+  GCedTreeNode<Item>::Trace(visitor);
+  visitor->Trace(pWidget);
+}
diff --git a/xfa/fwl/cfwl_widgetmgr.h b/xfa/fwl/cfwl_widgetmgr.h
index cae13fc..34867ba 100644
--- a/xfa/fwl/cfwl_widgetmgr.h
+++ b/xfa/fwl/cfwl_widgetmgr.h
@@ -11,17 +11,22 @@
 #include <memory>
 
 #include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/tree_node.h"
+#include "fxjs/gc/gced_tree_node.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxgraphics/cxfa_graphics.h"
 
 class CFWL_Message;
 class CXFA_Graphics;
 class CFX_Matrix;
+class CFWL_App;
 class CFWL_Widget;
 
-class CFWL_WidgetMgr {
+class CFWL_WidgetMgr final : public cppgc::GarbageCollected<CFWL_WidgetMgr> {
  public:
-  class AdapterIface {
+  class AdapterIface : public cppgc::GarbageCollectedMixin {
    public:
     virtual ~AdapterIface() {}
     virtual void RepaintWidget(CFWL_Widget* pWidget) = 0;
@@ -32,9 +37,11 @@
                              CFX_RectF* pPopupRect) = 0;
   };
 
-  explicit CFWL_WidgetMgr(AdapterIface* pAdapterNative);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_WidgetMgr();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   void OnProcessMessageToForm(CFWL_Message* pMessage);
   void OnDrawWidget(CFWL_Widget* pWidget,
                     CXFA_Graphics* pGraphics,
@@ -60,15 +67,22 @@
                           CFX_RectF* pPopupRect) const;
 
  private:
-  class Item : public TreeNode<Item> {
+  class Item final : public GCedTreeNode<Item> {
    public:
-    Item();
-    explicit Item(CFWL_Widget* widget);
+    CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
     ~Item() final;
 
-    CFWL_Widget* const pWidget;
+    // GcedTreeNode:
+    void Trace(cppgc::Visitor* visitor) const override;
+
+    cppgc::Member<CFWL_Widget> const pWidget;
+
+   private:
+    explicit Item(CFWL_Widget* widget);
   };
 
+  CFWL_WidgetMgr(AdapterIface* pAdapter, CFWL_App* pApp);
+
   CFWL_Widget* GetPriorSiblingWidget(CFWL_Widget* pWidget) const;
   CFWL_Widget* GetLastChildWidget(CFWL_Widget* pWidget) const;
 
@@ -81,8 +95,9 @@
                     CXFA_Graphics* pGraphics,
                     const CFX_Matrix* pMatrix);
 
-  std::map<const CFWL_Widget*, std::unique_ptr<Item>> m_mapWidgetItem;
-  UnownedPtr<AdapterIface> const m_pAdapter;
+  cppgc::Member<AdapterIface> const m_pAdapter;
+  cppgc::Member<CFWL_App> const m_pApp;
+  std::map<const CFWL_Widget*, cppgc::Member<Item>> m_mapWidgetItem;
 };
 
 #endif  // XFA_FWL_CFWL_WIDGETMGR_H_
diff --git a/xfa/fwl/ifwl_themeprovider.h b/xfa/fwl/ifwl_themeprovider.h
index f23acff..4d780e3 100644
--- a/xfa/fwl/ifwl_themeprovider.h
+++ b/xfa/fwl/ifwl_themeprovider.h
@@ -12,6 +12,7 @@
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/fx_dib.h"
+#include "v8/include/cppgc/garbage-collected.h"
 
 class CFGAS_GEFont;
 class CFWL_ThemeBackground;
@@ -20,9 +21,8 @@
 class CFWL_Widget;
 class CFWL_WidgetTP;
 
-class IFWL_ThemeProvider {
+class IFWL_ThemeProvider : public cppgc::GarbageCollectedMixin {
  public:
-  IFWL_ThemeProvider();
   virtual ~IFWL_ThemeProvider();
 
   virtual void DrawBackground(const CFWL_ThemeBackground& pParams) = 0;
@@ -42,6 +42,8 @@
       const CFWL_ThemePart& pThemePart) const = 0;
 
  protected:
+  IFWL_ThemeProvider();
+
   CFWL_WidgetTP* GetTheme(const CFWL_Widget* pWidget) const;
 
  private:
diff --git a/xfa/fxfa/cxfa_ffapp.cpp b/xfa/fxfa/cxfa_ffapp.cpp
index 5377f19..47b8b0b 100644
--- a/xfa/fxfa/cxfa_ffapp.cpp
+++ b/xfa/fxfa/cxfa_ffapp.cpp
@@ -32,12 +32,19 @@
 
 CXFA_FFApp::CXFA_FFApp(IXFA_AppProvider* pProvider)
     : m_pProvider(pProvider), m_pXFAFontMgr(std::make_unique<CXFA_FontMgr>()) {
-  // Ensure fully initialized before making an app based on |this|.
-  m_pFWLApp = std::make_unique<CFWL_App>(this);
+  // Ensure fully initialized before making objects based on |this|.
+  m_pFWLApp = cppgc::MakeGarbageCollected<CFWL_App>(
+      GetHeap()->GetAllocationHandle(), this);
 }
 
 CXFA_FFApp::~CXFA_FFApp() = default;
 
+void CXFA_FFApp::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pAdapterWidgetMgr);
+  visitor->Trace(m_pFWLTheme);
+  visitor->Trace(m_pFWLApp);
+}
+
 CFGAS_FontMgr* CXFA_FFApp::GetFGASFontMgr() {
   if (!m_pFGASFontMgr) {
     m_pFGASFontMgr = std::make_unique<CFGAS_FontMgr>();
@@ -50,18 +57,21 @@
 }
 
 bool CXFA_FFApp::LoadFWLTheme(CXFA_FFDoc* doc) {
-  auto fwl_theme = std::make_unique<CXFA_FWLTheme>(this);
+  auto* fwl_theme = cppgc::MakeGarbageCollected<CXFA_FWLTheme>(
+      GetHeap()->GetAllocationHandle(), this);
   if (!fwl_theme->LoadCalendarFont(doc))
     return false;
 
-  m_pFWLTheme = std::move(fwl_theme);
+  m_pFWLTheme = fwl_theme;
   return true;
 }
 
 CFWL_WidgetMgr::AdapterIface* CXFA_FFApp::GetWidgetMgrAdapter() {
-  if (!m_pAdapterWidgetMgr)
-    m_pAdapterWidgetMgr = std::make_unique<CXFA_FWLAdapterWidgetMgr>();
-  return m_pAdapterWidgetMgr.get();
+  if (!m_pAdapterWidgetMgr) {
+    m_pAdapterWidgetMgr = cppgc::MakeGarbageCollected<CXFA_FWLAdapterWidgetMgr>(
+        GetHeap()->GetAllocationHandle());
+  }
+  return m_pAdapterWidgetMgr;
 }
 
 TimerHandlerIface* CXFA_FFApp::GetTimerHandler() {
@@ -69,7 +79,7 @@
 }
 
 IFWL_ThemeProvider* CXFA_FFApp::GetThemeProvider() {
-  return m_pFWLTheme.get();
+  return m_pFWLTheme;
 }
 
 cppgc::Heap* CXFA_FFApp::GetHeap() {
diff --git a/xfa/fxfa/cxfa_ffapp.h b/xfa/fxfa/cxfa_ffapp.h
index 4466982..cc068dd 100644
--- a/xfa/fxfa/cxfa_ffapp.h
+++ b/xfa/fxfa/cxfa_ffapp.h
@@ -10,6 +10,9 @@
 #include <memory>
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fxfa/fxfa.h"
 
@@ -19,14 +22,16 @@
 class CXFA_FWLAdapterWidgetMgr;
 class CXFA_FWLTheme;
 
-class CXFA_FFApp : public CFWL_App::AdapterIface {
+class CXFA_FFApp : public cppgc::GarbageCollected<CXFA_FFApp>,
+                   public CFWL_App::AdapterIface {
  public:
   static void SkipFontLoadForTesting(bool skip);
 
-  explicit CXFA_FFApp(IXFA_AppProvider* pProvider);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFApp() override;
 
   // CFWL_App::AdapterIface:
+  void Trace(cppgc::Visitor* visitor) const override;
   CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() override;
   TimerHandlerIface* GetTimerHandler() override;
   IFWL_ThemeProvider* GetThemeProvider() override;
@@ -37,10 +42,12 @@
   CFGAS_FontMgr* GetFGASFontMgr();
 
   IXFA_AppProvider* GetAppProvider() const { return m_pProvider.Get(); }
-  const CFWL_App* GetFWLApp() const { return m_pFWLApp.get(); }
+  CFWL_App* GetFWLApp() const { return m_pFWLApp; }
   CXFA_FontMgr* GetXFAFontMgr() const { return m_pXFAFontMgr.get(); }
 
  private:
+  explicit CXFA_FFApp(IXFA_AppProvider* pProvider);
+
   UnownedPtr<IXFA_AppProvider> const m_pProvider;
 
   // The fonts stored in the font manager may have been created by the default
@@ -55,12 +62,9 @@
   // of the DEFFontMgr so this goes away. Bug 561.
   std::unique_ptr<CFGAS_FontMgr> m_pFGASFontMgr;
   std::unique_ptr<CXFA_FontMgr> m_pXFAFontMgr;
-  std::unique_ptr<CXFA_FWLAdapterWidgetMgr> m_pAdapterWidgetMgr;
-
-  // |m_pFWLApp| has to be released first, then |m_pFWLTheme| since the former
-  // may refers to theme manager and the latter refers to font manager.
-  std::unique_ptr<CXFA_FWLTheme> m_pFWLTheme;
-  std::unique_ptr<CFWL_App> m_pFWLApp;
+  cppgc::Member<CXFA_FWLAdapterWidgetMgr> m_pAdapterWidgetMgr;
+  cppgc::Member<CXFA_FWLTheme> m_pFWLTheme;
+  cppgc::Member<CFWL_App> m_pFWLApp;
 };
 
 #endif  // XFA_FXFA_CXFA_FFAPP_H_
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 7804b95..dc557e6 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -57,9 +57,9 @@
                        CPDF_Document* pPDFDoc,
                        cppgc::Heap* pHeap)
     : m_pDocEnvironment(pDocEnvironment),
-      m_pApp(pApp),
       m_pPDFDoc(pPDFDoc),
       m_pHeap(pHeap),
+      m_pApp(pApp),
       m_pNotify(cppgc::MakeGarbageCollected<CXFA_FFNotify>(
           pHeap->GetAllocationHandle(),
           this)),
@@ -82,6 +82,7 @@
 }
 
 void CXFA_FFDoc::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pApp);
   visitor->Trace(m_pNotify);
   visitor->Trace(m_pDocument);
   visitor->Trace(m_DocView);
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 0272876..176b7b8 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -116,10 +116,10 @@
   bool BuildDoc(CFX_XMLDocument* pXML);
 
   UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
-  UnownedPtr<CXFA_FFApp> const m_pApp;
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
   UnownedPtr<cppgc::Heap> const m_pHeap;
   UnownedPtr<CFX_XMLDocument> m_pXMLDoc;
+  cppgc::Member<CXFA_FFApp> const m_pApp;
   cppgc::Member<CXFA_FFNotify> m_pNotify;
   cppgc::Member<CXFA_Document> m_pDocument;
   cppgc::Member<CXFA_FFDocView> m_DocView;
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 85930b9..b23e002 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -239,7 +239,7 @@
   visitor->Trace(m_pDocView);
 }
 
-const CFWL_App* CXFA_FFWidget::GetFWLApp() {
+CFWL_App* CXFA_FFWidget::GetFWLApp() const {
   return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
 }
 
diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h
index f49eaf6..2eabd8b 100644
--- a/xfa/fxfa/cxfa_ffwidget.h
+++ b/xfa/fxfa/cxfa_ffwidget.h
@@ -168,6 +168,7 @@
   CXFA_FFDoc* GetDoc();
   CXFA_FFApp* GetApp();
   IXFA_AppProvider* GetAppProvider();
+  CFWL_App* GetFWLApp() const;
   void InvalidateRect();
   bool IsFocused() const {
     return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_Focused);
@@ -176,8 +177,6 @@
   bool IsLayoutRectEmpty();
   CXFA_LayoutItem* GetParent();
   bool IsAncestorOf(CXFA_FFWidget* pWidget);
-  const CFWL_App* GetFWLApp();
-
   bool HasEventUnderHandler(XFA_EVENTTYPE eEventType,
                             CXFA_FFWidgetHandler* pHandler);
   bool ProcessEventUnderHandler(CXFA_EventParam* params,
diff --git a/xfa/fxfa/cxfa_fontmgr.cpp b/xfa/fxfa/cxfa_fontmgr.cpp
index 0e7485e..7f7f4b1 100644
--- a/xfa/fxfa/cxfa_fontmgr.cpp
+++ b/xfa/fxfa/cxfa_fontmgr.cpp
@@ -15,6 +15,7 @@
 #include "core/fxge/cfx_gemodule.h"
 #include "xfa/fgas/font/cfgas_defaultfontmanager.h"
 #include "xfa/fgas/font/cfgas_gefont.h"
+#include "xfa/fgas/font/cfgas_pdffontmgr.h"
 #include "xfa/fgas/font/fgas_fontutils.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
diff --git a/xfa/fxfa/cxfa_fwladapterwidgetmgr.cpp b/xfa/fxfa/cxfa_fwladapterwidgetmgr.cpp
index a1b4082..829799a 100644
--- a/xfa/fxfa/cxfa_fwladapterwidgetmgr.cpp
+++ b/xfa/fxfa/cxfa_fwladapterwidgetmgr.cpp
@@ -9,10 +9,12 @@
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 
-CXFA_FWLAdapterWidgetMgr::CXFA_FWLAdapterWidgetMgr() {}
+CXFA_FWLAdapterWidgetMgr::CXFA_FWLAdapterWidgetMgr() = default;
 
 CXFA_FWLAdapterWidgetMgr::~CXFA_FWLAdapterWidgetMgr() = default;
 
+void CXFA_FWLAdapterWidgetMgr::Trace(cppgc::Visitor* visitor) const {}
+
 void CXFA_FWLAdapterWidgetMgr::RepaintWidget(CFWL_Widget* pWidget) {
   if (!pWidget)
     return;
diff --git a/xfa/fxfa/cxfa_fwladapterwidgetmgr.h b/xfa/fxfa/cxfa_fwladapterwidgetmgr.h
index 4a50c28..f271a76 100644
--- a/xfa/fxfa/cxfa_fwladapterwidgetmgr.h
+++ b/xfa/fxfa/cxfa_fwladapterwidgetmgr.h
@@ -9,21 +9,30 @@
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 
 class CFWL_Widget;
 
-class CXFA_FWLAdapterWidgetMgr : public CFWL_WidgetMgr::AdapterIface {
+class CXFA_FWLAdapterWidgetMgr
+    : public cppgc::GarbageCollected<CXFA_FWLAdapterWidgetMgr>,
+      public CFWL_WidgetMgr::AdapterIface {
  public:
-  CXFA_FWLAdapterWidgetMgr();
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FWLAdapterWidgetMgr() override;
 
+  // CFWL_WidgetMgr::AdapterIface:
+  void Trace(cppgc::Visitor* visitor) const override;
   void RepaintWidget(CFWL_Widget* pWidget) override;
   bool GetPopupPos(CFWL_Widget* pWidget,
                    float fMinHeight,
                    float fMaxHeight,
                    const CFX_RectF& rtAnchor,
                    CFX_RectF* pPopupRect) override;
+
+ private:
+  CXFA_FWLAdapterWidgetMgr();
 };
 
 #endif  // XFA_FXFA_CXFA_FWLADAPTERWIDGETMGR_H_
diff --git a/xfa/fxfa/cxfa_fwltheme.cpp b/xfa/fxfa/cxfa_fwltheme.cpp
index 14d342b..5fabf10 100644
--- a/xfa/fxfa/cxfa_fwltheme.cpp
+++ b/xfa/fxfa/cxfa_fwltheme.cpp
@@ -51,6 +51,17 @@
 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp)
     : m_pTextOut(std::make_unique<CFDE_TextOut>()), m_pApp(pApp) {}
 
+CXFA_FWLTheme::~CXFA_FWLTheme() = default;
+
+void CXFA_FWLTheme::PreFinalize() {
+  m_pTextOut.reset();
+  CFWL_FontManager::DestroyInstance();
+}
+
+void CXFA_FWLTheme::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pApp);
+}
+
 bool CXFA_FWLTheme::LoadCalendarFont(CXFA_FFDoc* doc) {
   for (size_t i = 0; !m_pCalendarFont && i < pdfium::size(g_FWLTheme_CalFonts);
        ++i) {
@@ -69,11 +80,6 @@
   return m_pCalendarFont != nullptr;
 }
 
-CXFA_FWLTheme::~CXFA_FWLTheme() {
-  m_pTextOut.reset();
-  CFWL_FontManager::DestroyInstance();
-}
-
 void CXFA_FWLTheme::DrawBackground(const CFWL_ThemeBackground& pParams) {
   GetTheme(pParams.m_pWidget)->DrawBackground(pParams);
 }
diff --git a/xfa/fxfa/cxfa_fwltheme.h b/xfa/fxfa/cxfa_fwltheme.h
index a84122a..a4a250e 100644
--- a/xfa/fxfa/cxfa_fwltheme.h
+++ b/xfa/fxfa/cxfa_fwltheme.h
@@ -9,20 +9,28 @@
 
 #include <memory>
 
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/prefinalizer.h"
 #include "xfa/fwl/ifwl_themeprovider.h"
 
 class CFDE_TextOut;
 class CXFA_FFApp;
 class CXFA_FFDoc;
 
-class CXFA_FWLTheme final : public IFWL_ThemeProvider {
+class CXFA_FWLTheme final : public cppgc::GarbageCollected<CXFA_FWLTheme>,
+                            public IFWL_ThemeProvider {
+  CPPGC_USING_PRE_FINALIZER(CXFA_FWLTheme, PreFinalize);
+
  public:
-  explicit CXFA_FWLTheme(CXFA_FFApp* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FWLTheme() override;
 
-  bool LoadCalendarFont(CXFA_FFDoc* doc);
+  void PreFinalize();
 
   // IFWL_ThemeProvider:
+  void Trace(cppgc::Visitor* visitor) const override;
   void DrawBackground(const CFWL_ThemeBackground& pParams) override;
   void DrawText(const CFWL_ThemeText& pParams) override;
   void CalcTextRect(const CFWL_ThemeText& pParams, CFX_RectF* pRect) override;
@@ -37,11 +45,15 @@
   FX_COLORREF GetTextColor(const CFWL_ThemePart& pThemePart) const override;
   CFX_SizeF GetSpaceAboveBelow(const CFWL_ThemePart& pThemePart) const override;
 
+  bool LoadCalendarFont(CXFA_FFDoc* doc);
+
  private:
+  explicit CXFA_FWLTheme(CXFA_FFApp* pApp);
+
   std::unique_ptr<CFDE_TextOut> m_pTextOut;
   RetainPtr<CFGAS_GEFont> m_pCalendarFont;
+  cppgc::Member<CXFA_FFApp> const m_pApp;
   WideString m_wsResource;
-  UnownedPtr<CXFA_FFApp> const m_pApp;
   CFX_RectF m_Rect;
 };