Garbage collect all the CXFA_Nodes.

First CL moving XFA code onto the CPPGC heap.

Bug: pdfium:1563
Change-Id: Ied4b4503ae4c476ea385dc994050193d0eedbbb3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/72292
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
index 52215ef..d7f5cb5 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -497,9 +497,9 @@
   CPDF_Document::Extension* pContext = m_pFormFillEnv->GetDocExtension();
   if (pContext && pContext->ContainsExtensionFullForm()) {
     CXFA_FFPageView* pageView = protector->GetXFAPageView();
-    std::unique_ptr<IXFA_WidgetIterator> pWidgetHandler =
-        pageView->CreateFormWidgetIterator(XFA_WidgetStatus_Visible |
-                                           XFA_WidgetStatus_Viewable);
+    IXFA_WidgetIterator* pWidgetHandler =
+        pageView->CreateGCedFormWidgetIterator(XFA_WidgetStatus_Visible |
+                                               XFA_WidgetStatus_Viewable);
 
     while (CXFA_FFWidget* pXFAAnnot = pWidgetHandler->MoveToNext()) {
       std::unique_ptr<CPDFSDK_Annot> pNewAnnot =
diff --git a/fpdfsdk/fpdfxfa/BUILD.gn b/fpdfsdk/fpdfxfa/BUILD.gn
index 658f050..56f2c00 100644
--- a/fpdfsdk/fpdfxfa/BUILD.gn
+++ b/fpdfsdk/fpdfxfa/BUILD.gn
@@ -31,6 +31,7 @@
     "../../xfa/fxfa",
     "../../xfa/fxfa/parser",
     "../../xfa/fxgraphics",
+    "//v8:cppgc",
   ]
   configs += [ "../../:pdfium_core_config" ]
   visibility = [ "../../*" ]
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 1ab40d8..8eeba7d 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -85,9 +85,9 @@
 
 CPDFXFA_Context::CPDFXFA_Context(CPDF_Document* pPDFDoc)
     : m_pPDFDoc(pPDFDoc),
-      m_pGCHeap(FXGC_CreateHeap()),
       m_pXFAApp(std::make_unique<CXFA_FFApp>(this)),
-      m_pDocEnv(std::make_unique<CPDFXFA_DocEnvironment>(this)) {
+      m_pDocEnv(std::make_unique<CPDFXFA_DocEnvironment>(this)),
+      m_pGCHeap(FXGC_CreateHeap()) {
   ASSERT(m_pPDFDoc);
 }
 
@@ -102,9 +102,10 @@
   // The layout data can have pointers back into the script context. That
   // context will be different if the form fill environment closes, so, force
   // the layout data to clear.
-  if (m_pXFADoc && m_pXFADoc->GetXFADoc())
+  if (m_pXFADoc && m_pXFADoc->GetXFADoc()) {
     m_pXFADoc->GetXFADoc()->ClearLayoutData();
-
+    FXGC_ForceGarbageCollection(m_pGCHeap.get());
+  }
   m_pFormFillEnv.Reset(pFormFillEnv);
 }
 
@@ -131,16 +132,17 @@
     return false;
   }
 
-  AutoNuller<std::unique_ptr<CXFA_FFDoc>> doc_nuller(&m_pXFADoc);
-  m_pXFADoc =
-      CXFA_FFDoc::CreateAndOpen(m_pXFAApp.get(), m_pDocEnv.get(),
-                                m_pPDFDoc.Get(), m_pGCHeap.get(), m_pXML.get());
-  if (!m_pXFADoc) {
+  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_pPDFDoc.Get(), m_pGCHeap.get());
+
+  if (!m_pXFADoc->OpenDoc(m_pXML.get())) {
     FXSYS_SetLastError(FPDF_ERR_XFALOAD);
     return false;
   }
 
-  if (!m_pXFAApp->LoadFWLTheme(m_pXFADoc.get())) {
+  if (!m_pXFAApp->LoadFWLTheme(m_pXFADoc)) {
     FXSYS_SetLastError(FPDF_ERR_XFALAYOUT);
     return false;
   }
@@ -151,10 +153,12 @@
   else
     m_FormType = FormType::kXFAForeground;
 
-  AutoNuller<UnownedPtr<CXFA_FFDocView>> view_nuller(&m_pXFADocView);
+  AutoNuller<cppgc::Persistent<CXFA_FFDocView>> view_nuller(&m_pXFADocView);
   m_pXFADocView = m_pXFADoc->CreateDocView();
 
   if (m_pXFADocView->StartLayout() < 0) {
+    m_pXFADoc->GetXFADoc()->ClearLayoutData();
+    FXGC_ForceGarbageCollection(m_pGCHeap.get());
     FXSYS_SetLastError(FPDF_ERR_XFALAYOUT);
     return false;
   }
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index c4e0039..14daddb 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -18,6 +18,7 @@
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
 #include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 
 class CFX_XMLDocument;
@@ -47,7 +48,7 @@
   }
 
   CFX_XMLDocument* GetXMLDoc() { return m_pXML.get(); }
-  CXFA_FFDoc* GetXFADoc() { return m_pXFADoc.get(); }
+  CXFA_FFDoc* GetXFADoc() { return m_pXFADoc; }
   CXFA_FFDocView* GetXFADocView() const { return m_pXFADocView.Get(); }
   CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
     return m_pFormFillEnv.Get();
@@ -115,16 +116,16 @@
   // The order in which the following members are destroyed is critical.
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
   std::unique_ptr<CFX_XMLDocument> m_pXML;
-  FXGCScopedHeap m_pGCHeap;
-  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
   std::unique_ptr<CXFA_FFApp> const m_pXFAApp;
+  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
   std::vector<RetainPtr<CPDFXFA_Page>> m_XFAPageList;
 
   // Can't outlive |m_pFormFillEnv|.
   std::unique_ptr<CPDFXFA_DocEnvironment> m_pDocEnv;
 
-  std::unique_ptr<CXFA_FFDoc> m_pXFADoc;
-  UnownedPtr<CXFA_FFDocView> m_pXFADocView;
+  FXGCScopedHeap m_pGCHeap;
+  cppgc::Persistent<CXFA_FFDoc> m_pXFADoc;          // Can't outlive |m_pGCHeap|
+  cppgc::Persistent<CXFA_FFDocView> m_pXFADocView;  // Can't outlive |m_pGCHeap|
 };
 
 #endif  // FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
index a1111a3..d216986 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
@@ -192,8 +192,8 @@
 
   ObservedPtr<CPDFSDK_Annot> pObservedAnnot(pSDKAnnot);
   CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
-  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator =
-      xfa_page_view->CreateTraverseWidgetIterator(kIteratorFilter);
+  IXFA_WidgetIterator* pWidgetIterator =
+      xfa_page_view->CreateGCedTraverseWidgetIterator(kIteratorFilter);
 
   // Check |pSDKAnnot| again because JS may have destroyed it
   if (!pObservedAnnot)
@@ -217,8 +217,8 @@
     return nullptr;
 
   ObservedPtr<CPDFSDK_PageView> watched_page_view(page_view);
-  std::unique_ptr<IXFA_WidgetIterator> it =
-      xfa_page_view->CreateTraverseWidgetIterator(kIteratorFilter);
+  IXFA_WidgetIterator* it =
+      xfa_page_view->CreateGCedTraverseWidgetIterator(kIteratorFilter);
   if (!watched_page_view)
     return nullptr;
 
@@ -239,8 +239,8 @@
   if (!pWidgetHandler)
     return -1;
 
-  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator =
-      pPageView->CreateFormWidgetIterator(XFA_WidgetStatus_Viewable);
+  IXFA_WidgetIterator* pWidgetIterator =
+      pPageView->CreateGCedFormWidgetIterator(XFA_WidgetStatus_Viewable);
 
   CXFA_FFWidget* pXFAAnnot;
   while ((pXFAAnnot = pWidgetIterator->MoveToNext()) != nullptr) {
@@ -265,9 +265,8 @@
   gs.SetClipRect(rectClip);
 
   CXFA_FFPageView* xfaView = GetXFAPageView();
-  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator =
-      xfaView->CreateFormWidgetIterator(XFA_WidgetStatus_Visible |
-                                        XFA_WidgetStatus_Viewable);
+  IXFA_WidgetIterator* pWidgetIterator = xfaView->CreateGCedFormWidgetIterator(
+      XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable);
 
   while (1) {
     CXFA_FFWidget* pWidget = pWidgetIterator->MoveToNext();
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index 0606037..26a07e9 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -177,12 +177,11 @@
     v8::Isolate* pIsolate,
     const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
     CFXJSE_HostObject* pGlobalObject,
-    std::unique_ptr<CXFA_ThisProxy> pProxy) {
+    CXFA_ThisProxy* pProxy) {
   CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
 
   // Private constructor.
-  auto pContext =
-      pdfium::WrapUnique(new CFXJSE_Context(pIsolate, std::move(pProxy)));
+  auto pContext = pdfium::WrapUnique(new CFXJSE_Context(pIsolate, pProxy));
   v8::Local<v8::ObjectTemplate> hObjectTemplate;
   if (pGlobalClass) {
     CFXJSE_Class* pGlobalClassObj =
@@ -214,9 +213,8 @@
   return pContext;
 }
 
-CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate,
-                               std::unique_ptr<CXFA_ThisProxy> pProxy)
-    : m_pIsolate(pIsolate), m_pProxy(std::move(pProxy)) {}
+CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy)
+    : m_pIsolate(pIsolate), m_pProxy(pProxy) {}
 
 CFXJSE_Context::~CFXJSE_Context() = default;
 
diff --git a/fxjs/xfa/cfxjse_context.h b/fxjs/xfa/cfxjse_context.h
index ed302f0..8437a8b 100644
--- a/fxjs/xfa/cfxjse_context.h
+++ b/fxjs/xfa/cfxjse_context.h
@@ -12,6 +12,7 @@
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/persistent.h"
 #include "v8/include/v8.h"
 
 class CFXJSE_Class;
@@ -26,7 +27,7 @@
       v8::Isolate* pIsolate,
       const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
       CFXJSE_HostObject* pGlobalObject,
-      std::unique_ptr<CXFA_ThisProxy> pProxy);
+      CXFA_ThisProxy* pProxy);
 
   ~CFXJSE_Context();
 
@@ -41,14 +42,14 @@
                      CFXJSE_Value* lpNewThisObject);
 
  private:
-  CFXJSE_Context(v8::Isolate* pIsolate, std::unique_ptr<CXFA_ThisProxy> pProxy);
+  CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy);
   CFXJSE_Context(const CFXJSE_Context&) = delete;
   CFXJSE_Context& operator=(const CFXJSE_Context&) = delete;
 
   v8::Global<v8::Context> m_hContext;
   UnownedPtr<v8::Isolate> m_pIsolate;
   std::vector<std::unique_ptr<CFXJSE_Class>> m_rgClasses;
-  std::unique_ptr<CXFA_ThisProxy> m_pProxy;
+  cppgc::Persistent<CXFA_ThisProxy> m_pProxy;
 };
 
 void FXJSE_UpdateObjectBinding(v8::Local<v8::Object> hObject,
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index f43a777..664eaed 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -148,7 +148,7 @@
   } else {
     btScript = FX_UTF8Encode(wsScript);
   }
-  AutoRestorer<UnownedPtr<CXFA_Object>> nodeRestorer(&m_pThisObject);
+  AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
   m_pThisObject = pThisObject;
 
   CFXJSE_Value* pValue =
@@ -497,10 +497,11 @@
   if (!pScriptNode || !pSubform)
     return nullptr;
 
-  auto proxy = std::make_unique<CXFA_ThisProxy>(pSubform, pScriptNode);
-  CJX_Object* js_object = proxy->JSObject();
+  auto* proxy = cppgc::MakeGarbageCollected<CXFA_ThisProxy>(
+      pScriptNode->GetDocument()->GetHeap()->GetAllocationHandle(), pSubform,
+      pScriptNode);
   auto pNewContext = CFXJSE_Context::Create(
-      GetIsolate(), &VariablesClassDescriptor, js_object, std::move(proxy));
+      GetIsolate(), &VariablesClassDescriptor, proxy->JSObject(), proxy);
   RemoveBuiltInObjs(pNewContext.get());
   pNewContext->EnableCompatibleMode();
   CFXJSE_Context* pResult = pNewContext.get();
@@ -547,7 +548,7 @@
   CXFA_Node* pThisObject = pParent->GetParent();
   CFXJSE_Context* pVariablesContext =
       CreateVariablesContext(pScriptNode, pThisObject);
-  AutoRestorer<UnownedPtr<CXFA_Object>> nodeRestorer(&m_pThisObject);
+  AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
   m_pThisObject = pThisObject;
   return pVariablesContext->ExecuteScript(btScript.c_str(), hRetValue.get(),
                                           nullptr);
@@ -784,13 +785,14 @@
   return pValue;
 }
 
-void CFXJSE_Engine::SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray) {
+void CFXJSE_Engine::SetNodesOfRunScript(
+    std::vector<cppgc::Persistent<CXFA_Node>>* pArray) {
   m_pScriptNodeArray = pArray;
 }
 
 void CFXJSE_Engine::AddNodesOfRunScript(CXFA_Node* pNode) {
   if (m_pScriptNodeArray && !pdfium::Contains(*m_pScriptNodeArray, pNode))
-    m_pScriptNodeArray->push_back(pNode);
+    m_pScriptNodeArray->emplace_back(pNode);
 }
 
 CXFA_Object* CFXJSE_Engine::ToXFAObject(v8::Local<v8::Value> obj) {
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index 0f64095..59c72b0 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -13,6 +13,7 @@
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/cfx_v8.h"
+#include "v8/include/cppgc/persistent.h"
 #include "v8/include/v8.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
@@ -85,17 +86,19 @@
 
   CFXJSE_Value* GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
 
-  CXFA_Object* GetThisObject() const { return m_pThisObject.Get(); }
+  CXFA_Object* GetThisObject() const { return m_pThisObject; }
   CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass.Get(); }
 
-  void SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray);
+  void SetNodesOfRunScript(std::vector<cppgc::Persistent<CXFA_Node>>* pArray);
   void AddNodesOfRunScript(CXFA_Node* pNode);
 
   void SetRunAtType(XFA_AttributeValue eRunAt) { m_eRunAtType = eRunAt; }
   bool IsRunAtClient() { return m_eRunAtType != XFA_AttributeValue::Server; }
 
   CXFA_Script::Type GetType();
-  std::vector<CXFA_Node*>* GetUpObjectArray() { return &m_upObjectArray; }
+  std::vector<cppgc::Persistent<CXFA_Node>>* GetUpObjectArray() {
+    return &m_upObjectArray;
+  }
   CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
 
   CXFA_Object* ToXFAObject(v8::Local<v8::Value> obj);
@@ -121,7 +124,7 @@
   bool RunVariablesScript(CXFA_Node* pScriptNode);
 
   UnownedPtr<CJS_Runtime> const m_pSubordinateRuntime;
-  UnownedPtr<CXFA_Document> const m_pDocument;
+  cppgc::WeakPersistent<CXFA_Document> const m_pDocument;
   std::unique_ptr<CFXJSE_Context> m_JsContext;
   UnownedPtr<CFXJSE_Class> m_pJsClass;
   CXFA_Script::Type m_eScriptType = CXFA_Script::Type::Unknown;
@@ -130,11 +133,11 @@
   std::map<CJX_Object*, std::unique_ptr<CFXJSE_Value>> m_mapObjectToValue;
   std::map<CJX_Object*, std::unique_ptr<CFXJSE_Context>> m_mapVariableToContext;
   UnownedPtr<CXFA_EventParam> m_eventParam;
-  std::vector<CXFA_Node*> m_upObjectArray;
-  UnownedPtr<std::vector<CXFA_Node*>> m_pScriptNodeArray;
+  std::vector<cppgc::Persistent<CXFA_Node>> m_upObjectArray;
+  UnownedPtr<std::vector<cppgc::Persistent<CXFA_Node>>> m_pScriptNodeArray;
   std::unique_ptr<CFXJSE_ResolveProcessor> const m_ResolveProcessor;
   std::unique_ptr<CFXJSE_FormCalcContext> m_FM2JSContext;
-  UnownedPtr<CXFA_Object> m_pThisObject;
+  cppgc::Persistent<CXFA_Object> m_pThisObject;
   XFA_AttributeValue m_eRunAtType = XFA_AttributeValue::Client;
 };
 
diff --git a/fxjs/xfa/cfxjse_nodehelper.h b/fxjs/xfa/cfxjse_nodehelper.h
index da2cce3..6060544 100644
--- a/fxjs/xfa/cfxjse_nodehelper.h
+++ b/fxjs/xfa/cfxjse_nodehelper.h
@@ -8,6 +8,7 @@
 #define FXJS_XFA_CFXJSE_NODEHELPER_H_
 
 #include "core/fxcrt/fx_string.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/fxfa_basic.h"
 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
 
@@ -30,8 +31,8 @@
   XFA_ResolveNode_RSType m_iCreateFlag = XFA_ResolveNode_RSType_CreateNodeOne;
   size_t m_iCreateCount = 0;
   int32_t m_iCurAllStart = -1;
-  UnownedPtr<CXFA_Node> m_pCreateParent;
-  UnownedPtr<CXFA_Node> m_pAllStartParent;
+  cppgc::Persistent<CXFA_Node> m_pCreateParent;
+  cppgc::Persistent<CXFA_Node> m_pAllStartParent;
 };
 
 #endif  // FXJS_XFA_CFXJSE_NODEHELPER_H_
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 6605942..c086453 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -99,7 +99,7 @@
     if (pObjNode) {
       rnd.m_Objects.emplace_back(pObjNode);
     } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
-      rnd.m_Objects.push_back(rnd.m_CurObject);
+      rnd.m_Objects.emplace_back(rnd.m_CurObject.Get());
     } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
                ResolveForAttributeRs(rnd.m_CurObject.Get(), rnd,
                                      rnd.m_wsName.AsStringView())) {
@@ -153,7 +153,7 @@
   WideString wsCondition = rnd.m_wsCondition;
   int32_t iNameLen = wsName.GetLength();
   if (iNameLen == 1) {
-    rnd.m_Objects.push_back(rnd.m_CurObject);
+    rnd.m_Objects.emplace_back(rnd.m_CurObject.Get());
     return true;
   }
   if (rnd.m_nLevel > 0)
@@ -649,7 +649,7 @@
 void CFXJSE_ResolveProcessor::FilterCondition(WideString wsCondition,
                                               CFXJSE_ResolveNodeData* pRnd) {
   size_t iCurIndex = 0;
-  const std::vector<CXFA_Node*>* pArray = pRnd->m_pSC->GetUpObjectArray();
+  const auto* pArray = pRnd->m_pSC->GetUpObjectArray();
   if (!pArray->empty()) {
     CXFA_Node* pNode = pArray->back();
     bool bIsProperty = pNode->IsProperty();
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.h b/fxjs/xfa/cfxjse_resolveprocessor.h
index 509161f..7340e3f 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.h
+++ b/fxjs/xfa/cfxjse_resolveprocessor.h
@@ -12,6 +12,7 @@
 
 #include "core/fxcrt/fx_string.h"
 #include "fxjs/xfa/cfxjse_engine.h"
+#include "v8/include/cppgc/macros.h"
 #include "xfa/fxfa/fxfa_basic.h"
 #include "xfa/fxfa/parser/xfa_basic_data.h"
 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
@@ -19,6 +20,8 @@
 class CFXJSE_NodeHelper;
 
 class CFXJSE_ResolveNodeData {
+  CPPGC_STACK_ALLOCATED();  // Allows Raw/Unowned pointers.
+
  public:
   explicit CFXJSE_ResolveNodeData(CFXJSE_Engine* pSC);
   ~CFXJSE_ResolveNodeData();
diff --git a/fxjs/xfa/cjx_container.cpp b/fxjs/xfa/cjx_container.cpp
index 6500cce..3352f18 100644
--- a/fxjs/xfa/cjx_container.cpp
+++ b/fxjs/xfa/cjx_container.cpp
@@ -11,6 +11,7 @@
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_field.h"
@@ -38,8 +39,11 @@
 CJS_Result CJX_Container::getDeltas(
     CFX_V8* runtime,
     const std::vector<v8::Local<v8::Value>>& params) {
-  auto* pList = static_cast<CXFA_ArrayNodeList*>(GetDocument()->AddOwnedList(
-      std::make_unique<CXFA_ArrayNodeList>(GetDocument())));
+  CXFA_Document* pDoc = GetDocument();
+  auto* pList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+      pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+  pDoc->GetNodeOwner()->PersistList(pList);
+
   auto* pEngine = static_cast<CFXJSE_Engine*>(runtime);
   return CJS_Result::Success(pEngine->NewXFAObject(
       pList, pEngine->GetJseNormalClass()->GetTemplate()));
diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp
index a4112ac..f7e7465 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.cpp
+++ b/fxjs/xfa/cjx_eventpseudomodel.cpp
@@ -185,7 +185,7 @@
   if (!pWidgetHandler)
     return CJS_Result::Success();
 
-  pWidgetHandler->ProcessEvent(pEventParam->m_pTarget.Get(), pEventParam);
+  pWidgetHandler->ProcessEvent(pEventParam->m_pTarget, pEventParam);
   return CJS_Result::Success();
 }
 
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp
index a743809..0963874 100644
--- a/fxjs/xfa/cjx_form.cpp
+++ b/fxjs/xfa/cjx_form.cpp
@@ -11,6 +11,7 @@
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
@@ -46,9 +47,11 @@
   if (!pDataNode)
     return CJS_Result::Failure(JSMessage::kValueError);
 
-  auto* pFormNodes =
-      static_cast<CXFA_ArrayNodeList*>(GetDocument()->AddOwnedList(
-          std::make_unique<CXFA_ArrayNodeList>(GetDocument())));
+  CXFA_Document* pDoc = GetDocument();
+  auto* pFormNodes = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+      pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+  pDoc->GetNodeOwner()->PersistList(pFormNodes);
+
   CFXJSE_Value* value = pEngine->GetOrCreateJSBindingFromMap(pFormNodes);
   return CJS_Result::Success(
       value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_layoutpseudomodel.cpp b/fxjs/xfa/cjx_layoutpseudomodel.cpp
index feb0410..da8181f 100644
--- a/fxjs/xfa/cjx_layoutpseudomodel.cpp
+++ b/fxjs/xfa/cjx_layoutpseudomodel.cpp
@@ -6,7 +6,6 @@
 
 #include "fxjs/xfa/cjx_layoutpseudomodel.h"
 
-#include <memory>
 #include <set>
 #include <utility>
 
@@ -16,6 +15,7 @@
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
@@ -369,10 +369,11 @@
   if (!pNotify)
     return CJS_Result::Success();
 
-  auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(GetDocument());
-  auto* pArrayNodeList =
-      static_cast<CXFA_ArrayNodeList*>(GetDocument()->AddOwnedList(
-          std::make_unique<CXFA_ArrayNodeList>(GetDocument())));
+  CXFA_Document* pDoc = GetDocument();
+  auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDoc);
+  auto* pArrayNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+      pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+  pDoc->GetNodeOwner()->PersistList(pArrayNodeList);
   pArrayNodeList->SetArrayNodeList(
       GetObjArray(pDocLayout, iIndex, wsType, bOnPageArea));
 
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index 4207b47..a34654c 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -18,6 +18,7 @@
 #include "fxjs/xfa/jse_define.h"
 #include "third_party/base/optional.h"
 #include "third_party/base/span.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/fxfa_basic.h"
 #include "xfa/fxfa/parser/cxfa_measurement.h"
 
@@ -114,8 +115,8 @@
   void SetCalcRecursionCount(size_t count) { calc_recursion_count_ = count; }
   size_t GetCalcRecursionCount() const { return calc_recursion_count_; }
 
-  void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_.Reset(item); }
-  CXFA_LayoutItem* GetLayoutItem() const { return layout_item_.Get(); }
+  void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_ = item; }
+  CXFA_LayoutItem* GetLayoutItem() const { return layout_item_; }
 
   bool HasMethod(const WideString& func) const;
   CJS_Result RunMethod(const WideString& func,
@@ -260,8 +261,8 @@
   void RemoveMapModuleKey(void* pKey);
   void MoveBufferMapData(CXFA_Object* pDstModule);
 
-  UnownedPtr<CXFA_Object> const object_;
-  UnownedPtr<CXFA_LayoutItem> layout_item_;
+  UnownedPtr<CXFA_Object> object_;
+  CXFA_LayoutItem* layout_item_ = nullptr;
   std::unique_ptr<XFA_MAPMODULEDATA> map_module_data_;
   std::unique_ptr<CXFA_CalcData> calc_data_;
   std::map<ByteString, CJX_MethodCall> method_specs_;
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index fdb3c36..151b0f9 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -13,6 +13,7 @@
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
 #include "xfa/fxfa/parser/cxfa_attachnodelist.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
@@ -135,10 +136,12 @@
     return;
   }
 
-  auto* pNodeList =
-      static_cast<CXFA_AttachNodeList*>(GetDocument()->AddOwnedList(
-          std::make_unique<CXFA_AttachNodeList>(GetDocument(), GetXFANode())));
-  CFXJSE_Engine* pEngine = GetDocument()->GetScriptContext();
+  CXFA_Document* pDoc = GetDocument();
+  auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_AttachNodeList>(
+      pDoc->GetHeap()->GetAllocationHandle(), pDoc, GetXFANode());
+  pDoc->GetNodeOwner()->PersistList(pNodeList);
+
+  CFXJSE_Engine* pEngine = pDoc->GetScriptContext();
   pValue->SetHostObject(pNodeList->JSObject(), pEngine->GetJseNormalClass());
 }
 
@@ -206,12 +209,15 @@
     refNode = GetXFANode();
 
   XFA_RESOLVENODE_RS resolveNodeRS;
-  CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
+  CXFA_Document* pDoc = GetDocument();
+  CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
   pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
                                  &resolveNodeRS, dwFlag, nullptr);
-  auto* pNodeList =
-      static_cast<CXFA_ArrayNodeList*>(GetDocument()->AddOwnedList(
-          std::make_unique<CXFA_ArrayNodeList>(GetDocument())));
+
+  auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+      pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+  pDoc->GetNodeOwner()->PersistList(pNodeList);
+
   if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
     for (auto& pObject : resolveNodeRS.objects) {
       if (pObject->IsNode())
diff --git a/xfa/fxfa/BUILD.gn b/xfa/fxfa/BUILD.gn
index 1f03242..dd4215d 100644
--- a/xfa/fxfa/BUILD.gn
+++ b/xfa/fxfa/BUILD.gn
@@ -108,8 +108,8 @@
     "../fxgraphics",
     "layout",
     "parser",
-    "//v8:cppgc",
   ]
+  public_deps = [ "//v8:cppgc" ]
   allow_circular_includes_from = [
     "../../fxjs",
     "layout",
diff --git a/xfa/fxfa/cxfa_eventparam.cpp b/xfa/fxfa/cxfa_eventparam.cpp
index c3f229d..8e88b62 100644
--- a/xfa/fxfa/cxfa_eventparam.cpp
+++ b/xfa/fxfa/cxfa_eventparam.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fxfa/cxfa_eventparam.h"
 
 #include "xfa/fxfa/fxfa.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
 
 CXFA_EventParam::CXFA_EventParam() = default;
 
diff --git a/xfa/fxfa/cxfa_eventparam.h b/xfa/fxfa/cxfa_eventparam.h
index a670263..3900de9 100644
--- a/xfa/fxfa/cxfa_eventparam.h
+++ b/xfa/fxfa/cxfa_eventparam.h
@@ -9,6 +9,7 @@
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/macros.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
 class CXFA_Node;
@@ -48,6 +49,8 @@
 };
 
 class CXFA_EventParam {
+  CPPGC_STACK_ALLOCATED();  // Raw/Unowned pointers allowed.
+
  public:
   CXFA_EventParam();
   CXFA_EventParam(const CXFA_EventParam& other);
diff --git a/xfa/fxfa/cxfa_ffarc.h b/xfa/fxfa/cxfa_ffarc.h
index 022e25e..4be0b9f 100644
--- a/xfa/fxfa/cxfa_ffarc.h
+++ b/xfa/fxfa/cxfa_ffarc.h
@@ -11,13 +11,16 @@
 
 class CXFA_FFArc final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFArc(CXFA_Node* pnode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFArc() override;
 
   // CXFA_FFWidget
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
                     HighlightOption highlight) override;
+
+ private:
+  explicit CXFA_FFArc(CXFA_Node* pnode);
 };
 
 #endif  // XFA_FXFA_CXFA_FFARC_H_
diff --git a/xfa/fxfa/cxfa_ffbarcode.cpp b/xfa/fxfa/cxfa_ffbarcode.cpp
index 5ba551b..be5c0e1 100644
--- a/xfa/fxfa/cxfa_ffbarcode.cpp
+++ b/xfa/fxfa/cxfa_ffbarcode.cpp
@@ -138,12 +138,14 @@
 
 CXFA_FFBarcode::~CXFA_FFBarcode() = default;
 
+void CXFA_FFBarcode::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFTextEdit::Trace(visitor);
+  visitor->Trace(barcode_);
+}
+
 bool CXFA_FFBarcode::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_Barcode>(GetFWLApp());
   CFWL_Barcode* pFWLBarcode = pNew.get();
   SetNormalWidget(std::move(pNew));
diff --git a/xfa/fxfa/cxfa_ffbarcode.h b/xfa/fxfa/cxfa_ffbarcode.h
index 83e0884..97d6f4e 100644
--- a/xfa/fxfa/cxfa_ffbarcode.h
+++ b/xfa/fxfa/cxfa_ffbarcode.h
@@ -9,6 +9,8 @@
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxbarcode/BC_Library.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_fftextedit.h"
 
@@ -90,9 +92,11 @@
  public:
   static const BarCodeInfo* GetBarcodeTypeByName(const WideString& wsName);
 
-  CXFA_FFBarcode(CXFA_Node* pNode, CXFA_Barcode* barcode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFBarcode() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_FFTextEdit
   bool LoadWidget() override;
   void RenderWidget(CXFA_Graphics* pGS,
@@ -104,7 +108,9 @@
                                 FWL_MouseCommand command) override;
 
  private:
-  UnownedPtr<CXFA_Barcode> const barcode_;
+  CXFA_FFBarcode(CXFA_Node* pNode, CXFA_Barcode* barcode);
+
+  cppgc::Member<CXFA_Barcode> const barcode_;
 };
 
 #endif  // XFA_FXFA_CXFA_FFBARCODE_H_
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.cpp b/xfa/fxfa/cxfa_ffcheckbutton.cpp
index a094058..81c63af 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.cpp
+++ b/xfa/fxfa/cxfa_ffcheckbutton.cpp
@@ -31,12 +31,14 @@
 
 CXFA_FFCheckButton::~CXFA_FFCheckButton() = default;
 
+void CXFA_FFCheckButton::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFField::Trace(visitor);
+  visitor->Trace(button_);
+}
+
 bool CXFA_FFCheckButton::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_CheckBox>(GetFWLApp());
   CFWL_CheckBox* pCheckBox = pNew.get();
   SetNormalWidget(std::move(pNew));
@@ -255,9 +257,6 @@
   if (!GetNormalWidget() || !IsButtonDown())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(false);
   SendMessageToFWLWidget(std::make_unique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::LeftButtonUp, dwFlags,
@@ -299,24 +298,16 @@
   if (!GetNormalWidget())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
   SetFWLCheckState(m_pNode->GetCheckState());
   GetNormalWidget()->Update();
   return true;
 }
 
 void CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   CXFA_FFField::OnProcessEvent(pEvent);
   switch (pEvent->GetType()) {
     case CFWL_Event::Type::CheckStateChanged: {
@@ -356,9 +347,6 @@
 
 void CXFA_FFCheckButton::OnDrawWidget(CXFA_Graphics* pGraphics,
                                       const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
 }
 
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.h b/xfa/fxfa/cxfa_ffcheckbutton.h
index 30d59fa..35f8ba5 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.h
+++ b/xfa/fxfa/cxfa_ffcheckbutton.h
@@ -8,6 +8,8 @@
 #define XFA_FXFA_CXFA_FFCHECKBUTTON_H_
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
@@ -16,9 +18,11 @@
 
 class CXFA_FFCheckButton final : public CXFA_FFField {
  public:
-  CXFA_FFCheckButton(CXFA_Node* pNode, CXFA_CheckButton* button);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFCheckButton() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_FFField
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
@@ -38,6 +42,8 @@
   void SetFWLCheckState(XFA_CHECKSTATE eCheckState);
 
  private:
+  CXFA_FFCheckButton(CXFA_Node* pNode, CXFA_CheckButton* button);
+
   bool CommitData() override;
   bool IsDataChanged() override;
   void CapLeftRightPlacement(const CXFA_Margin* captionMargin);
@@ -45,8 +51,8 @@
   XFA_CHECKSTATE FWLState2XFAState();
 
   UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<CXFA_CheckButton> const button_;
   CFX_RectF m_CheckBoxRect;
-  UnownedPtr<CXFA_CheckButton> const button_;
 };
 
 #endif  // XFA_FXFA_CXFA_FFCHECKBUTTON_H_
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index db71ab9..cfd28f4 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -51,9 +51,6 @@
 bool CXFA_FFComboBox::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_ComboBox>(GetFWLApp());
   CFWL_ComboBox* pComboBox = pNew.get();
   SetNormalWidget(std::move(pNew));
@@ -107,9 +104,6 @@
 }
 
 bool CXFA_FFComboBox::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!CXFA_FFField::OnRButtonUp(dwFlags, point))
     return false;
 
@@ -118,9 +112,6 @@
 }
 
 bool CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pNewWatched(pNewWidget);
   if (!ProcessCommittedData())
     UpdateFWLData();
@@ -209,8 +200,6 @@
   if (!pComboBox)
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
   std::vector<int32_t> iSelArray = m_pNode->GetSelectedItems();
   if (!iSelArray.empty()) {
     pComboBox->SetCurSel(iSelArray.front());
@@ -250,32 +239,20 @@
 }
 
 bool CXFA_FFComboBox::Undo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return m_pNode->IsChoiceListAllowTextEntry() &&
          ToComboBox(GetNormalWidget())->EditUndo();
 }
 
 bool CXFA_FFComboBox::Redo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return m_pNode->IsChoiceListAllowTextEntry() &&
          ToComboBox(GetNormalWidget())->EditRedo();
 }
 
 Optional<WideString> CXFA_FFComboBox::Copy() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToComboBox(GetNormalWidget())->EditCopy();
 }
 
 Optional<WideString> CXFA_FFComboBox::Cut() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   if (!m_pNode->IsChoiceListAllowTextEntry())
     return {};
 
@@ -283,31 +260,19 @@
 }
 
 bool CXFA_FFComboBox::Paste(const WideString& wsPaste) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return m_pNode->IsChoiceListAllowTextEntry() &&
          ToComboBox(GetNormalWidget())->EditPaste(wsPaste);
 }
 
 void CXFA_FFComboBox::SelectAll() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToComboBox(GetNormalWidget())->EditSelectAll();
 }
 
 void CXFA_FFComboBox::Delete() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToComboBox(GetNormalWidget())->EditDelete();
 }
 
 void CXFA_FFComboBox::DeSelect() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToComboBox(GetNormalWidget())->EditDeSelect();
 }
 
@@ -343,9 +308,6 @@
 
 void CXFA_FFComboBox::OnTextChanged(CFWL_Widget* pWidget,
                                     const WideString& wsChanged) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw);
   eParam.m_wsChange = wsChanged;
@@ -353,9 +315,6 @@
 }
 
 void CXFA_FFComboBox::OnSelectChanged(CFWL_Widget* pWidget, bool bLButtonUp) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw);
   FWLEventSelChange(&eParam);
@@ -364,9 +323,6 @@
 }
 
 void CXFA_FFComboBox::OnPreOpen(CFWL_Widget* pWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_eType = XFA_EVENT_PreOpen;
   eParam.m_pTarget = m_pNode.Get();
@@ -374,9 +330,6 @@
 }
 
 void CXFA_FFComboBox::OnPostOpen(CFWL_Widget* pWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_eType = XFA_EVENT_PostOpen;
   eParam.m_pTarget = m_pNode.Get();
@@ -384,16 +337,10 @@
 }
 
 void CXFA_FFComboBox::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFComboBox::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   CXFA_FFField::OnProcessEvent(pEvent);
   switch (pEvent->GetType()) {
     case CFWL_Event::Type::SelectChanged: {
@@ -422,8 +369,5 @@
 
 void CXFA_FFComboBox::OnDrawWidget(CXFA_Graphics* pGraphics,
                                    const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
 }
diff --git a/xfa/fxfa/cxfa_ffcombobox.h b/xfa/fxfa/cxfa_ffcombobox.h
index 3e14dc6..d2f7d66 100644
--- a/xfa/fxfa/cxfa_ffcombobox.h
+++ b/xfa/fxfa/cxfa_ffcombobox.h
@@ -14,7 +14,7 @@
 
 class CXFA_FFComboBox final : public CXFA_FFDropDown {
  public:
-  explicit CXFA_FFComboBox(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFComboBox() override;
 
   // CXFA_FFDropDown:
@@ -62,6 +62,8 @@
   void SetItemState(int32_t nIndex, bool bSelected);
 
  private:
+  explicit CXFA_FFComboBox(CXFA_Node* pNode);
+
   // CXFA_FFField:
   bool PtInActiveRect(const CFX_PointF& point) override;
   bool CommitData() override;
diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
index 1dd0d3a..363ab8b 100644
--- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp
+++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
@@ -44,9 +44,6 @@
 bool CXFA_FFDateTimeEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNewPicker = std::make_unique<CFWL_DateTimePicker>(GetFWLApp());
   CFWL_DateTimePicker* pWidget = pNewPicker.get();
   SetNormalWidget(std::move(pNewPicker));
@@ -159,8 +156,6 @@
   if (!GetNormalWidget())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
   XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
   if (IsFocused())
     eType = XFA_VALUEPICTURE_Edit;
@@ -192,9 +187,6 @@
                                           int32_t iYear,
                                           int32_t iMonth,
                                           int32_t iDay) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   WideString wsPicture = m_pNode->GetPictureContent(XFA_VALUEPICTURE_Edit);
   CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocaleMgr());
   date.SetDate(CFX_DateTime(iYear, iMonth, iDay, 0, 0, 0, 0));
@@ -216,9 +208,6 @@
 }
 
 void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) {
     auto* event = static_cast<CFWL_EventSelectChanged*>(pEvent);
     OnSelectChanged(GetNormalWidget(), event->iYear, event->iMonth,
@@ -259,51 +248,30 @@
 }
 
 bool CXFA_FFDateTimeEdit::Undo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return GetPickerWidget()->Undo();
 }
 
 bool CXFA_FFDateTimeEdit::Redo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return GetPickerWidget()->Redo();
 }
 
 Optional<WideString> CXFA_FFDateTimeEdit::Cut() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return GetPickerWidget()->Cut();
 }
 
 bool CXFA_FFDateTimeEdit::Paste(const WideString& wsPaste) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return GetPickerWidget()->Paste(wsPaste);
 }
 
 void CXFA_FFDateTimeEdit::SelectAll() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   GetPickerWidget()->SelectAll();
 }
 
 void CXFA_FFDateTimeEdit::Delete() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   GetPickerWidget()->ClearText();
 }
 
 void CXFA_FFDateTimeEdit::DeSelect() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   GetPickerWidget()->ClearSelection();
 }
 
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 1a4c43b..61124a4 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -23,6 +23,7 @@
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "fxjs/xfa/cjx_object.h"
 #include "third_party/base/ptr_util.h"
+#include "v8/include/cppgc/allocation.h"
 #include "v8/include/cppgc/heap.h"
 #include "xfa/fgas/font/cfgas_pdffontmgr.h"
 #include "xfa/fwl/cfwl_notedriver.h"
@@ -51,26 +52,6 @@
 
 FX_IMAGEDIB_AND_DPI::~FX_IMAGEDIB_AND_DPI() = default;
 
-// static
-std::unique_ptr<CXFA_FFDoc> CXFA_FFDoc::CreateAndOpen(
-    CXFA_FFApp* pApp,
-    IXFA_DocEnvironment* pDocEnvironment,
-    CPDF_Document* pPDFDoc,
-    cppgc::Heap* pGCHeap,
-    CFX_XMLDocument* pXML) {
-  ASSERT(pApp);
-  ASSERT(pDocEnvironment);
-  ASSERT(pPDFDoc);
-
-  // Use WrapUnique() to keep constructor private.
-  auto result = pdfium::WrapUnique(
-      new CXFA_FFDoc(pApp, pDocEnvironment, pPDFDoc, pGCHeap));
-  if (!result->OpenDoc(pXML))
-    return nullptr;
-
-  return result;
-}
-
 CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp,
                        IXFA_DocEnvironment* pDocEnvironment,
                        CPDF_Document* pPDFDoc,
@@ -79,30 +60,38 @@
       m_pApp(pApp),
       m_pPDFDoc(pPDFDoc),
       m_pHeap(pHeap),
-      m_pNotify(std::make_unique<CXFA_FFNotify>(this)),
-      m_pDocument(std::make_unique<CXFA_Document>(
-          m_pNotify.get(),
-          std::make_unique<CXFA_LayoutProcessor>(pHeap))) {}
+      m_pNotify(cppgc::MakeGarbageCollected<CXFA_FFNotify>(
+          pHeap->GetAllocationHandle(),
+          this)),
+      m_pDocument(cppgc::MakeGarbageCollected<CXFA_Document>(
+          pHeap->GetAllocationHandle(),
+          m_pNotify,
+          pHeap,
+          cppgc::MakeGarbageCollected<CXFA_LayoutProcessor>(
+              pHeap->GetAllocationHandle(),
+              pHeap))) {}
 
-CXFA_FFDoc::~CXFA_FFDoc() {
-  if (m_DocView) {
+CXFA_FFDoc::~CXFA_FFDoc() = default;
+
+void CXFA_FFDoc::PreFinalize() {
+  if (m_DocView)
     m_DocView->RunDocClose();
-    m_DocView.reset();
-  }
+
   if (m_pDocument)
     m_pDocument->ClearLayoutData();
+}
 
-  m_pDocument.reset();
-  m_pNotify.reset();
-  m_pPDFFontMgr.reset();
-  m_HashToDibDpiMap.clear();
+void CXFA_FFDoc::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pNotify);
+  visitor->Trace(m_pDocument);
+  visitor->Trace(m_DocView);
 }
 
 bool CXFA_FFDoc::BuildDoc(CFX_XMLDocument* pXML) {
   if (!pXML)
     return false;
 
-  CXFA_DocumentBuilder builder(m_pDocument.get());
+  CXFA_DocumentBuilder builder(m_pDocument);
   if (!builder.BuildDocument(pXML, XFA_PacketType::Xdp))
     return false;
 
@@ -111,20 +100,20 @@
 }
 
 CXFA_FFDocView* CXFA_FFDoc::CreateDocView() {
-  if (!m_DocView)
-    m_DocView = std::make_unique<CXFA_FFDocView>(this);
-
-  return m_DocView.get();
+  if (!m_DocView) {
+    m_DocView = cppgc::MakeGarbageCollected<CXFA_FFDocView>(
+        m_pHeap->GetAllocationHandle(), this);
+  }
+  return m_DocView;
 }
 
 CXFA_FFDocView* CXFA_FFDoc::GetDocView(CXFA_LayoutProcessor* pLayout) {
-  return m_DocView && m_DocView->GetLayoutProcessor() == pLayout
-             ? m_DocView.get()
-             : nullptr;
+  return m_DocView && m_DocView->GetLayoutProcessor() == pLayout ? m_DocView
+                                                                 : nullptr;
 }
 
 CXFA_FFDocView* CXFA_FFDoc::GetDocView() {
-  return m_DocView.get();
+  return m_DocView;
 }
 
 bool CXFA_FFDoc::OpenDoc(CFX_XMLDocument* pXML) {
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 4d7618d..7cc76d6 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -12,6 +12,11 @@
 
 #include "core/fxcrt/fx_stream.h"
 #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 "v8/include/cppgc/prefinalizer.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 
@@ -43,17 +48,18 @@
   int32_t iImageYDpi;
 };
 
-class CXFA_FFDoc {
- public:
-  static std::unique_ptr<CXFA_FFDoc> CreateAndOpen(
-      CXFA_FFApp* pApp,
-      IXFA_DocEnvironment* pDocEnvironment,
-      CPDF_Document* pPDFDoc,
-      cppgc::Heap* pGCHeap,
-      CFX_XMLDocument* pXML);
+class CXFA_FFDoc : public cppgc::GarbageCollected<CXFA_FFDoc> {
+  CPPGC_USING_PRE_FINALIZER(CXFA_FFDoc, PreFinalize);
 
+ public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFDoc();
 
+  void PreFinalize();
+  void Trace(cppgc::Visitor* visitor) const;
+
+  bool OpenDoc(CFX_XMLDocument* pXML);
+
   IXFA_DocEnvironment* GetDocEnvironment() const {
     return m_pDocEnvironment.Get();
   }
@@ -64,7 +70,7 @@
   }
 
   CXFA_FFDocView* CreateDocView();
-  CXFA_Document* GetXFADoc() const { return m_pDocument.get(); }
+  CXFA_Document* GetXFADoc() const { return m_pDocument; }
   CXFA_FFApp* GetApp() const { return m_pApp.Get(); }
   CPDF_Document* GetPDFDoc() const { return m_pPDFDoc.Get(); }
   CXFA_FFDocView* GetDocView(CXFA_LayoutProcessor* pLayout);
@@ -82,7 +88,6 @@
              IXFA_DocEnvironment* pDocEnvironment,
              CPDF_Document* pPDFDoc,
              cppgc::Heap* pHeap);
-  bool OpenDoc(CFX_XMLDocument* pXML);
   bool BuildDoc(CFX_XMLDocument* pXML);
 
   UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
@@ -90,9 +95,9 @@
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
   UnownedPtr<cppgc::Heap> const m_pHeap;
   UnownedPtr<CFX_XMLDocument> m_pXMLDoc;
-  std::unique_ptr<CXFA_FFNotify> m_pNotify;
-  std::unique_ptr<CXFA_Document> m_pDocument;
-  std::unique_ptr<CXFA_FFDocView> m_DocView;
+  cppgc::Member<CXFA_FFNotify> m_pNotify;
+  cppgc::Member<CXFA_Document> m_pDocument;
+  cppgc::Member<CXFA_FFDocView> m_DocView;
   std::unique_ptr<CFGAS_PDFFontMgr> m_pPDFFontMgr;
   std::map<uint32_t, FX_IMAGEDIB_AND_DPI> m_HashToDibDpiMap;
   FormType m_FormType = FormType::kXFAForeground;
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index 43bf0f9..971e7bf 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -62,6 +62,27 @@
 
 CXFA_FFDocView::~CXFA_FFDocView() = default;
 
+void CXFA_FFDocView::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDoc);
+  visitor->Trace(m_pWidgetHandler);
+  visitor->Trace(m_pFocusNode);
+
+  for (const auto& node : m_ValidateNodes)
+    visitor->Trace(node);
+
+  for (const auto& node : m_CalculateNodes)
+    visitor->Trace(node);
+
+  for (const auto& node : m_NewAddedNodes)
+    visitor->Trace(node);
+
+  for (const auto& node : m_BindItems)
+    visitor->Trace(node);
+
+  for (const auto& node : m_IndexChangedSubforms)
+    visitor->Trace(node);
+}
+
 void CXFA_FFDocView::InitLayout(CXFA_Node* pNode) {
   RunBindItems();
   ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize, false, true);
@@ -277,9 +298,11 @@
 }
 
 CXFA_FFWidgetHandler* CXFA_FFDocView::GetWidgetHandler() {
-  if (!m_pWidgetHandler)
-    m_pWidgetHandler = std::make_unique<CXFA_FFWidgetHandler>(this);
-  return m_pWidgetHandler.get();
+  if (!m_pWidgetHandler) {
+    m_pWidgetHandler = cppgc::MakeGarbageCollected<CXFA_FFWidgetHandler>(
+        m_pDoc->GetHeap()->GetAllocationHandle(), this);
+  }
+  return m_pWidgetHandler;
 }
 
 std::unique_ptr<CXFA_ReadyNodeIterator>
@@ -293,10 +316,6 @@
   if (pNewFocus == m_pFocusWidget)
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |pNewFocus|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(
-      pNewFocus ? pNewFocus->GetLayoutItem() : nullptr);
-
   if (m_pFocusWidget) {
     CXFA_ContentLayoutItem* pItem = m_pFocusWidget->GetLayoutItem();
     if (pItem->TestStatusBits(XFA_WidgetStatus_Visible) &&
@@ -325,10 +344,9 @@
     m_pFocusNode = node->IsWidgetReady() ? node : nullptr;
     m_pFocusWidget.Reset(pNewFocus);
   } else {
-    m_pFocusNode.Reset();
+    m_pFocusNode.Clear();
     m_pFocusWidget.Reset();
   }
-
   return true;
 }
 
@@ -349,7 +367,7 @@
   if (m_pFocusNode != pWidget->GetNode())
     return;
 
-  m_pFocusNode.Reset();
+  m_pFocusNode = nullptr;
   m_pFocusWidget.Reset();
 }
 
diff --git a/xfa/fxfa/cxfa_ffdocview.h b/xfa/fxfa/cxfa_ffdocview.h
index 1df61ab..fe23f29 100644
--- a/xfa/fxfa/cxfa_ffdocview.h
+++ b/xfa/fxfa/cxfa_ffdocview.h
@@ -13,6 +13,10 @@
 
 #include "core/fxcrt/observed_ptr.h"
 #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 "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
@@ -44,11 +48,13 @@
   XFA_DOCVIEW_LAYOUTSTATUS_End
 };
 
-class CXFA_FFDocView {
+class CXFA_FFDocView : public cppgc::GarbageCollected<CXFA_FFDocView> {
  public:
-  explicit CXFA_FFDocView(CXFA_FFDoc* pDoc);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFDocView();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   CXFA_FFDoc* GetDoc() const { return m_pDoc.Get(); }
   int32_t StartLayout();
   int32_t DoLayout();
@@ -102,6 +108,8 @@
   std::vector<WideString> m_NullTestMsgArray;
 
  private:
+  explicit CXFA_FFDocView(CXFA_FFDoc* pDoc);
+
   bool RunEventLayoutReady();
   void RunBindItems();
   void InitCalculate(CXFA_Node* pNode);
@@ -117,15 +125,15 @@
   XFA_EventError RunCalculateWidgets();
   void RunSubformIndexChange();
 
-  UnownedPtr<CXFA_FFDoc> const m_pDoc;
-  std::unique_ptr<CXFA_FFWidgetHandler> m_pWidgetHandler;
-  UnownedPtr<CXFA_Node> m_pFocusNode;
+  cppgc::Member<CXFA_FFDoc> const m_pDoc;
+  cppgc::Member<CXFA_FFWidgetHandler> m_pWidgetHandler;
+  cppgc::Member<CXFA_Node> m_pFocusNode;
   ObservedPtr<CXFA_FFWidget> m_pFocusWidget;
-  std::deque<CXFA_Node*> m_ValidateNodes;
-  std::vector<CXFA_Node*> m_CalculateNodes;
-  std::deque<CXFA_BindItems*> m_BindItems;
-  std::deque<CXFA_Node*> m_NewAddedNodes;
-  std::deque<CXFA_Node*> m_IndexChangedSubforms;
+  std::deque<cppgc::Member<CXFA_Node>> m_ValidateNodes;
+  std::vector<cppgc::Member<CXFA_Node>> m_CalculateNodes;
+  std::deque<cppgc::Member<CXFA_BindItems>> m_BindItems;
+  std::deque<cppgc::Member<CXFA_Node>> m_NewAddedNodes;
+  std::deque<cppgc::Member<CXFA_Node>> m_IndexChangedSubforms;
   XFA_DOCVIEW_LAYOUTSTATUS m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None;
   int32_t m_iLock = 0;
 };
diff --git a/xfa/fxfa/cxfa_ffdropdown.h b/xfa/fxfa/cxfa_ffdropdown.h
index b1751b4..7aa1b7c 100644
--- a/xfa/fxfa/cxfa_ffdropdown.h
+++ b/xfa/fxfa/cxfa_ffdropdown.h
@@ -14,6 +14,7 @@
 
 class CXFA_FFDropDown : public CXFA_FFField {
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFDropDown() override;
 
   // CXFA_FFField:
diff --git a/xfa/fxfa/cxfa_ffexclgroup.h b/xfa/fxfa/cxfa_ffexclgroup.h
index a14e071..5e97ca5 100644
--- a/xfa/fxfa/cxfa_ffexclgroup.h
+++ b/xfa/fxfa/cxfa_ffexclgroup.h
@@ -12,13 +12,16 @@
 
 class CXFA_FFExclGroup final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFExclGroup(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFExclGroup() override;
 
   // CXFA_FFWidget
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
                     HighlightOption highlight) override;
+
+ private:
+  explicit CXFA_FFExclGroup(CXFA_Node* pNode);
 };
 
 #endif  // XFA_FXFA_CXFA_FFEXCLGROUP_H_
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index 3b4e04c..6d0ee23 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -141,8 +141,6 @@
 }
 
 bool CXFA_FFField::LoadWidget() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
   m_pNode->LoadCaption(GetDoc());
   PerformLayout();
   return true;
@@ -374,9 +372,6 @@
 }
 
 bool CXFA_FFField::OnMouseEnter() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -387,9 +382,6 @@
 }
 
 bool CXFA_FFField::OnMouseExit() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -419,9 +411,6 @@
 }
 
 bool CXFA_FFField::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(true);
   SendMessageToFWLWidget(std::make_unique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::LeftButtonDown, dwFlags,
@@ -431,9 +420,6 @@
 }
 
 bool CXFA_FFField::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
   if (!IsButtonDown())
@@ -448,9 +434,6 @@
 }
 
 bool CXFA_FFField::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -462,9 +445,6 @@
 }
 
 bool CXFA_FFField::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -477,9 +457,6 @@
 bool CXFA_FFField::OnMouseWheel(uint32_t dwFlags,
                                 const CFX_PointF& point,
                                 const CFX_Vector& delta) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -490,9 +467,6 @@
 }
 
 bool CXFA_FFField::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(true);
   SendMessageToFWLWidget(std::make_unique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::RightButtonDown, dwFlags,
@@ -507,9 +481,6 @@
   if (!IsButtonDown())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(false);
   SendMessageToFWLWidget(std::make_unique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::RightButtonUp, dwFlags,
@@ -519,9 +490,6 @@
 }
 
 bool CXFA_FFField::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget())
     return false;
 
@@ -533,9 +501,6 @@
 }
 
 bool CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!CXFA_FFWidget::OnSetFocus(pOldWidget))
     return false;
 
@@ -551,9 +516,6 @@
 }
 
 bool CXFA_FFField::OnKillFocus(CXFA_FFWidget* pNewWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pNewWatched(pNewWidget);
   if (GetNormalWidget()) {
     SendMessageToFWLWidget(
@@ -565,9 +527,6 @@
 }
 
 bool CXFA_FFField::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
     return false;
 
@@ -578,9 +537,6 @@
 }
 
 bool CXFA_FFField::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
     return false;
 
@@ -591,9 +547,6 @@
 }
 
 bool CXFA_FFField::OnChar(uint32_t dwChar, uint32_t dwFlags) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!GetDoc()->GetXFADoc()->IsInteractive())
     return false;
   if (dwChar == XFA_FWL_VKEY_Tab)
@@ -771,9 +724,6 @@
 void CXFA_FFField::OnProcessMessage(CFWL_Message* pMessage) {}
 
 void CXFA_FFField::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   switch (pEvent->GetType()) {
     case CFWL_Event::Type::Mouse: {
       CFWL_EventMouse* event = static_cast<CFWL_EventMouse*>(pEvent);
diff --git a/xfa/fxfa/cxfa_fffield.h b/xfa/fxfa/cxfa_fffield.h
index 565df66..1906a32 100644
--- a/xfa/fxfa/cxfa_fffield.h
+++ b/xfa/fxfa/cxfa_fffield.h
@@ -24,7 +24,7 @@
  public:
   enum ShapeOption { kSquareShape = 0, kRoundShape };
 
-  explicit CXFA_FFField(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFField() override;
 
   virtual CXFA_FFDropDown* AsDropDown();
@@ -70,9 +70,14 @@
   uint32_t UpdateUIProperty();
 
  protected:
+  explicit CXFA_FFField(CXFA_Node* pNode);
+
   bool PtInActiveRect(const CFX_PointF& point) override;
 
   virtual void SetFWLRect();
+  virtual bool CommitData();
+  virtual bool IsDataChanged();
+
   CFWL_Widget* GetNormalWidget();
   const CFWL_Widget* GetNormalWidget() const;
   void SetNormalWidget(std::unique_ptr<CFWL_Widget> widget);
@@ -83,8 +88,6 @@
   int32_t CalculateOverride();
   int32_t CalculateNode(CXFA_Node* pNode);
   bool ProcessCommittedData();
-  virtual bool CommitData();
-  virtual bool IsDataChanged();
   void DrawHighlight(CXFA_Graphics* pGS,
                      CFX_Matrix* pMatrix,
                      HighlightOption highlight,
diff --git a/xfa/fxfa/cxfa_ffimage.cpp b/xfa/fxfa/cxfa_ffimage.cpp
index 2f77079..eeb0e24 100644
--- a/xfa/fxfa/cxfa_ffimage.cpp
+++ b/xfa/fxfa/cxfa_ffimage.cpp
@@ -26,9 +26,6 @@
 }
 
 bool CXFA_FFImage::LoadWidget() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   if (GetNode()->GetImageImage())
     return true;
 
diff --git a/xfa/fxfa/cxfa_ffimage.h b/xfa/fxfa/cxfa_ffimage.h
index 5d23f60..73fe546 100644
--- a/xfa/fxfa/cxfa_ffimage.h
+++ b/xfa/fxfa/cxfa_ffimage.h
@@ -11,7 +11,7 @@
 
 class CXFA_FFImage final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFImage(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFImage() override;
 
   // CXFA_FFWidget
@@ -20,6 +20,9 @@
                     HighlightOption highlight) override;
   bool IsLoaded() override;
   bool LoadWidget() override;
+
+ private:
+  explicit CXFA_FFImage(CXFA_Node* pNode);
 };
 
 #endif  // XFA_FXFA_CXFA_FFIMAGE_H_
diff --git a/xfa/fxfa/cxfa_ffimageedit.cpp b/xfa/fxfa/cxfa_ffimageedit.cpp
index 2eba6c5..55fd3d3 100644
--- a/xfa/fxfa/cxfa_ffimageedit.cpp
+++ b/xfa/fxfa/cxfa_ffimageedit.cpp
@@ -33,9 +33,6 @@
 bool CXFA_FFImageEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_PictureBox>(GetFWLApp());
   CFWL_PictureBox* pPictureBox = pNew.get();
   SetNormalWidget(std::move(pNew));
@@ -106,9 +103,6 @@
 
 bool CXFA_FFImageEdit::OnLButtonDown(uint32_t dwFlags,
                                      const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(true);
   SendMessageToFWLWidget(std::make_unique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::LeftButtonDown, dwFlags,
@@ -139,25 +133,16 @@
 }
 
 void CXFA_FFImageEdit::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFImageEdit::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   CXFA_FFField::OnProcessEvent(pEvent);
   m_pOldDelegate->OnProcessEvent(pEvent);
 }
 
 void CXFA_FFImageEdit::OnDrawWidget(CXFA_Graphics* pGraphics,
                                     const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
 }
 
diff --git a/xfa/fxfa/cxfa_ffimageedit.h b/xfa/fxfa/cxfa_ffimageedit.h
index f1233b3..1dd27d8 100644
--- a/xfa/fxfa/cxfa_ffimageedit.h
+++ b/xfa/fxfa/cxfa_ffimageedit.h
@@ -12,7 +12,7 @@
 
 class CXFA_FFImageEdit final : public CXFA_FFField {
  public:
-  explicit CXFA_FFImageEdit(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFImageEdit() override;
 
   // CXFA_FFField
@@ -31,6 +31,8 @@
   FormFieldType GetFormFieldType() override;
 
  private:
+  explicit CXFA_FFImageEdit(CXFA_Node* pNode);
+
   void SetFWLRect() override;
   bool UpdateFWLData() override;
   bool CommitData() override;
diff --git a/xfa/fxfa/cxfa_ffline.h b/xfa/fxfa/cxfa_ffline.h
index 62750d1..a7f3e26 100644
--- a/xfa/fxfa/cxfa_ffline.h
+++ b/xfa/fxfa/cxfa_ffline.h
@@ -11,7 +11,7 @@
 
 class CXFA_FFLine final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFLine(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFLine() override;
 
   // CXFA_FFWidget
@@ -20,6 +20,8 @@
                     HighlightOption highlight) override;
 
  private:
+  explicit CXFA_FFLine(CXFA_Node* pNode);
+
   void GetRectFromHand(CFX_RectF& rect,
                        XFA_AttributeValue iHand,
                        float fLineWidth);
diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp
index 34701da..15960d4 100644
--- a/xfa/fxfa/cxfa_fflistbox.cpp
+++ b/xfa/fxfa/cxfa_fflistbox.cpp
@@ -40,9 +40,6 @@
 bool CXFA_FFListBox::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_ListBox>(
       GetFWLApp(), CFWL_Widget::Properties(), nullptr);
   CFWL_ListBox* pListBox = pNew.get();
@@ -80,9 +77,6 @@
 }
 
 bool CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pNewWatched(pNewFocus);
   if (!ProcessCommittedData())
     UpdateFWLData();
@@ -148,9 +142,6 @@
   if (!pListBox)
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   std::vector<int32_t> iSelArray = m_pNode->GetSelectedItems();
   std::vector<CFWL_ListItem*> selItemArray(iSelArray.size());
   std::transform(iSelArray.begin(), iSelArray.end(), selItemArray.begin(),
@@ -165,9 +156,6 @@
 }
 
 void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_eType = XFA_EVENT_Change;
   eParam.m_pTarget = m_pNode.Get();
@@ -200,16 +188,10 @@
 }
 
 void CXFA_FFListBox::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFListBox::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   CXFA_FFField::OnProcessEvent(pEvent);
   switch (pEvent->GetType()) {
     case CFWL_Event::Type::SelectChanged:
@@ -223,9 +205,6 @@
 
 void CXFA_FFListBox::OnDrawWidget(CXFA_Graphics* pGraphics,
                                   const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
 }
 
diff --git a/xfa/fxfa/cxfa_fflistbox.h b/xfa/fxfa/cxfa_fflistbox.h
index 896ee61..11074ef 100644
--- a/xfa/fxfa/cxfa_fflistbox.h
+++ b/xfa/fxfa/cxfa_fflistbox.h
@@ -12,7 +12,7 @@
 
 class CXFA_FFListBox final : public CXFA_FFDropDown {
  public:
-  explicit CXFA_FFListBox(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFListBox() override;
 
   // CXFA_FFField:
@@ -32,6 +32,8 @@
   void SetItemState(int32_t nIndex, bool bSelected);
 
  private:
+  explicit CXFA_FFListBox(CXFA_Node* pNode);
+
   bool CommitData() override;
   bool UpdateFWLData() override;
   bool IsDataChanged() override;
diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp
index b728205..288c977 100644
--- a/xfa/fxfa/cxfa_ffnotify.cpp
+++ b/xfa/fxfa/cxfa_ffnotify.cpp
@@ -46,6 +46,10 @@
 
 CXFA_FFNotify::~CXFA_FFNotify() = default;
 
+void CXFA_FFNotify::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDoc);
+}
+
 void CXFA_FFNotify::OnPageEvent(CXFA_ViewLayoutItem* pSender,
                                 uint32_t dwEvent) {
   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
@@ -78,17 +82,17 @@
   }
 }
 
-std::unique_ptr<CXFA_FFPageView> CXFA_FFNotify::OnCreateViewLayoutItem(
-    CXFA_Node* pNode) {
+CXFA_FFPageView* CXFA_FFNotify::OnCreateViewLayoutItem(CXFA_Node* pNode) {
   if (pNode->GetElementType() != XFA_Element::PageArea)
     return nullptr;
 
   auto* pLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
-  return std::make_unique<CXFA_FFPageView>(m_pDoc->GetDocView(pLayout), pNode);
+  return cppgc::MakeGarbageCollected<CXFA_FFPageView>(
+      m_pDoc->GetHeap()->GetAllocationHandle(), m_pDoc->GetDocView(pLayout),
+      pNode);
 }
 
-std::unique_ptr<CXFA_FFWidget> CXFA_FFNotify::OnCreateContentLayoutItem(
-    CXFA_Node* pNode) {
+CXFA_FFWidget* CXFA_FFNotify::OnCreateContentLayoutItem(CXFA_Node* pNode) {
   ASSERT(pNode->GetElementType() != XFA_Element::ContentArea);
   ASSERT(pNode->GetElementType() != XFA_Element::PageArea);
 
@@ -96,15 +100,16 @@
   if (!pNode->HasCreatedUIWidget())
     return nullptr;
 
-  std::unique_ptr<CXFA_FFWidget> pWidget;
+  CXFA_FFWidget* pWidget = nullptr;
   switch (pNode->GetFFWidgetType()) {
     case XFA_FFWidgetType::kBarcode: {
       CXFA_Node* child = pNode->GetUIChildNode();
       if (child->GetElementType() != XFA_Element::Barcode)
         return nullptr;
 
-      pWidget = std::make_unique<CXFA_FFBarcode>(
-          pNode, static_cast<CXFA_Barcode*>(child));
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFBarcode>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode,
+          static_cast<CXFA_Barcode*>(child));
       break;
     }
     case XFA_FFWidgetType::kButton: {
@@ -112,8 +117,9 @@
       if (child->GetElementType() != XFA_Element::Button)
         return nullptr;
 
-      pWidget = std::make_unique<CXFA_FFPushButton>(
-          pNode, static_cast<CXFA_Button*>(child));
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFPushButton>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode,
+          static_cast<CXFA_Button*>(child));
       break;
     }
     case XFA_FFWidgetType::kCheckButton: {
@@ -121,61 +127,78 @@
       if (child->GetElementType() != XFA_Element::CheckButton)
         return nullptr;
 
-      pWidget = std::make_unique<CXFA_FFCheckButton>(
-          pNode, static_cast<CXFA_CheckButton*>(child));
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFCheckButton>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode,
+          static_cast<CXFA_CheckButton*>(child));
       break;
     }
     case XFA_FFWidgetType::kChoiceList: {
-      if (pNode->IsListBox())
-        pWidget = std::make_unique<CXFA_FFListBox>(pNode);
-      else
-        pWidget = std::make_unique<CXFA_FFComboBox>(pNode);
+      if (pNode->IsListBox()) {
+        pWidget = cppgc::MakeGarbageCollected<CXFA_FFListBox>(
+            m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
+      } else {
+        pWidget = cppgc::MakeGarbageCollected<CXFA_FFComboBox>(
+            m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
+      }
       break;
     }
     case XFA_FFWidgetType::kDateTimeEdit:
-      pWidget = std::make_unique<CXFA_FFDateTimeEdit>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFDateTimeEdit>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kImageEdit:
-      pWidget = std::make_unique<CXFA_FFImageEdit>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFImageEdit>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kNumericEdit:
-      pWidget = std::make_unique<CXFA_FFNumericEdit>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFNumericEdit>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kPasswordEdit: {
       CXFA_Node* child = pNode->GetUIChildNode();
       if (child->GetElementType() != XFA_Element::PasswordEdit)
         return nullptr;
 
-      pWidget = std::make_unique<CXFA_FFPasswordEdit>(
-          pNode, static_cast<CXFA_PasswordEdit*>(child));
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFPasswordEdit>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode,
+          static_cast<CXFA_PasswordEdit*>(child));
       break;
     }
     case XFA_FFWidgetType::kSignature:
-      pWidget = std::make_unique<CXFA_FFSignature>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFSignature>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kTextEdit:
-      pWidget = std::make_unique<CXFA_FFTextEdit>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFTextEdit>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kArc:
-      pWidget = std::make_unique<CXFA_FFArc>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFArc>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kLine:
-      pWidget = std::make_unique<CXFA_FFLine>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFLine>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kRectangle:
-      pWidget = std::make_unique<CXFA_FFRectangle>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFRectangle>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kText:
-      pWidget = std::make_unique<CXFA_FFText>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFText>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kImage:
-      pWidget = std::make_unique<CXFA_FFImage>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFImage>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kSubform:
-      pWidget = std::make_unique<CXFA_FFWidget>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFWidget>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kExclGroup:
-      pWidget = std::make_unique<CXFA_FFExclGroup>(pNode);
+      pWidget = cppgc::MakeGarbageCollected<CXFA_FFExclGroup>(
+          m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
       break;
     case XFA_FFWidgetType::kNone:
       return nullptr;
diff --git a/xfa/fxfa/cxfa_ffnotify.h b/xfa/fxfa/cxfa_ffnotify.h
index 295472d..f85dbe2 100644
--- a/xfa/fxfa/cxfa_ffnotify.h
+++ b/xfa/fxfa/cxfa_ffnotify.h
@@ -7,8 +7,10 @@
 #ifndef XFA_FXFA_CXFA_FFNOTIFY_H_
 #define XFA_FXFA_CXFA_FFNOTIFY_H_
 
-#include <memory>
-
+#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/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
@@ -20,11 +22,13 @@
 class CXFA_Script;
 class CXFA_ViewLayoutItem;
 
-class CXFA_FFNotify {
+class CXFA_FFNotify : public cppgc::GarbageCollected<CXFA_FFNotify> {
  public:
-  explicit CXFA_FFNotify(CXFA_FFDoc* pDoc);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFNotify();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   void OnPageEvent(CXFA_ViewLayoutItem* pSender, uint32_t dwEvent);
 
   void OnWidgetListItemAdded(CXFA_Node* pSender,
@@ -43,8 +47,9 @@
   void OnChildAdded(CXFA_Node* pSender);
   void OnChildRemoved();
 
-  std::unique_ptr<CXFA_FFPageView> OnCreateViewLayoutItem(CXFA_Node* pNode);
-  std::unique_ptr<CXFA_FFWidget> OnCreateContentLayoutItem(CXFA_Node* pNode);
+  // These two return new views/widgets from cppgc heap.
+  CXFA_FFPageView* OnCreateViewLayoutItem(CXFA_Node* pNode);
+  CXFA_FFWidget* OnCreateContentLayoutItem(CXFA_Node* pNode);
 
   void OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout,
                          CXFA_LayoutItem* pSender,
@@ -52,7 +57,6 @@
                          uint32_t dwStatus);
   void OnLayoutItemRemoving(CXFA_LayoutProcessor* pLayout,
                             CXFA_LayoutItem* pSender);
-
   void StartFieldDrawLayout(CXFA_Node* pItem,
                             float* pCalcWidth,
                             float* pCalcHeight);
@@ -74,7 +78,9 @@
   void SetFocusWidgetNode(CXFA_Node* pNode);
 
  private:
-  UnownedPtr<CXFA_FFDoc> const m_pDoc;
+  explicit CXFA_FFNotify(CXFA_FFDoc* pDoc);
+
+  cppgc::Member<CXFA_FFDoc> const m_pDoc;
 };
 
 #endif  // XFA_FXFA_CXFA_FFNOTIFY_H_
diff --git a/xfa/fxfa/cxfa_ffnumericedit.cpp b/xfa/fxfa/cxfa_ffnumericedit.cpp
index 5d0412e..81cc0d0 100644
--- a/xfa/fxfa/cxfa_ffnumericedit.cpp
+++ b/xfa/fxfa/cxfa_ffnumericedit.cpp
@@ -25,9 +25,6 @@
 bool CXFA_FFNumericEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNewEdit = std::make_unique<CFWL_Edit>(
       GetFWLApp(), CFWL_Widget::Properties(), nullptr);
   CFWL_Edit* pWidget = pNewEdit.get();
@@ -73,9 +70,6 @@
 }
 
 void CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   if (pEvent->GetType() == CFWL_Event::Type::Validate) {
     CFWL_EventValidate* event = static_cast<CFWL_EventValidate*>(pEvent);
     event->bValidate = OnValidate(GetNormalWidget(), event->wsInsert);
@@ -85,9 +79,6 @@
 }
 
 bool CXFA_FFNumericEdit::OnValidate(CFWL_Widget* pWidget, WideString& wsText) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   WideString wsPattern = m_pNode->GetPictureContent(XFA_VALUEPICTURE_Edit);
   if (!wsPattern.IsEmpty())
     return true;
diff --git a/xfa/fxfa/cxfa_ffpageview.cpp b/xfa/fxfa/cxfa_ffpageview.cpp
index 47b5fdd..5db297a 100644
--- a/xfa/fxfa/cxfa_ffpageview.cpp
+++ b/xfa/fxfa/cxfa_ffpageview.cpp
@@ -123,7 +123,8 @@
   ~CXFA_TabParam() = default;
 
   CXFA_FFWidget* GetWidget() const { return m_pItem->GetFFWidget(); }
-  const std::vector<RetainPtr<CXFA_ContentLayoutItem>>& GetChildren() const {
+  const std::vector<cppgc::Persistent<CXFA_ContentLayoutItem>>& GetChildren()
+      const {
     return m_Children;
   }
   void ClearChildren() { m_Children.clear(); }
@@ -134,8 +135,8 @@
   }
 
  private:
-  RetainPtr<CXFA_ContentLayoutItem> m_pItem;
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> m_Children;
+  cppgc::Persistent<CXFA_ContentLayoutItem> m_pItem;
+  std::vector<cppgc::Persistent<CXFA_ContentLayoutItem>> m_Children;
 };
 
 CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
@@ -143,8 +144,14 @@
 
 CXFA_FFPageView::~CXFA_FFPageView() = default;
 
+void CXFA_FFPageView::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pPageArea);
+  visitor->Trace(m_pDocView);
+  visitor->Trace(m_pLayoutItem);
+}
+
 CXFA_FFDocView* CXFA_FFPageView::GetDocView() const {
-  return m_pDocView.Get();
+  return m_pDocView;
 }
 
 CFX_RectF CXFA_FFPageView::GetPageViewRect() const {
@@ -164,15 +171,18 @@
   return GetPageMatrix(CFX_RectF(0, 0, pItem->GetPageSize()), rtDisp, iRotate);
 }
 
-std::unique_ptr<IXFA_WidgetIterator> CXFA_FFPageView::CreateFormWidgetIterator(
+IXFA_WidgetIterator* CXFA_FFPageView::CreateGCedFormWidgetIterator(
     uint32_t dwWidgetFilter) {
-  return std::make_unique<CXFA_FFPageWidgetIterator>(this, dwWidgetFilter);
+  return cppgc::MakeGarbageCollected<CXFA_FFPageWidgetIterator>(
+      GetDocView()->GetDoc()->GetHeap()->GetAllocationHandle(), this,
+      dwWidgetFilter);
 }
 
-std::unique_ptr<IXFA_WidgetIterator>
-CXFA_FFPageView::CreateTraverseWidgetIterator(uint32_t dwWidgetFilter) {
-  return std::make_unique<CXFA_FFTabOrderPageWidgetIterator>(this,
-                                                             dwWidgetFilter);
+IXFA_WidgetIterator* CXFA_FFPageView::CreateGCedTraverseWidgetIterator(
+    uint32_t dwWidgetFilter) {
+  return cppgc::MakeGarbageCollected<CXFA_FFTabOrderPageWidgetIterator>(
+      GetDocView()->GetDoc()->GetHeap()->GetAllocationHandle(), this,
+      dwWidgetFilter);
 }
 
 CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView,
@@ -261,6 +271,12 @@
 CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator() =
     default;
 
+void CXFA_FFTabOrderPageWidgetIterator::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pPageViewLayout);
+  for (const auto& item : m_TabOrderWidgetArray)
+    visitor->Trace(item);
+}
+
 void CXFA_FFTabOrderPageWidgetIterator::Reset() {
   CreateTabOrderWidgetArray();
   m_iCurWidget = -1;
@@ -356,12 +372,12 @@
 void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
   m_TabOrderWidgetArray.clear();
 
-  const std::vector<RetainPtr<CXFA_ContentLayoutItem>> items =
+  const std::vector<CXFA_ContentLayoutItem*> items =
       CreateSpaceOrderLayoutItems();
   if (items.empty())
     return;
 
-  RetainPtr<CXFA_ContentLayoutItem> item = items[0];
+  CXFA_ContentLayoutItem* item = items[0];
   while (m_TabOrderWidgetArray.size() < items.size()) {
     if (!pdfium::Contains(m_TabOrderWidgetArray, item)) {
       m_TabOrderWidgetArray.emplace_back(item);
@@ -444,9 +460,9 @@
     pContainer->AppendTabParam(pParam.get());
 }
 
-std::vector<RetainPtr<CXFA_ContentLayoutItem>>
+std::vector<CXFA_ContentLayoutItem*>
 CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderLayoutItems() {
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> items;
+  std::vector<CXFA_ContentLayoutItem*> items;
   CXFA_LayoutItemIterator sIterator(m_pPageViewLayout.Get());
   auto pParam = std::make_unique<CXFA_TabParam>();
   bool bCurrentItem = false;
diff --git a/xfa/fxfa/cxfa_ffpageview.h b/xfa/fxfa/cxfa_ffpageview.h
index ed22572..8ada06b 100644
--- a/xfa/fxfa/cxfa_ffpageview.h
+++ b/xfa/fxfa/cxfa_ffpageview.h
@@ -7,11 +7,14 @@
 #ifndef XFA_FXFA_CXFA_FFPAGEVIEW_H_
 #define XFA_FXFA_CXFA_FFPAGEVIEW_H_
 
-#include <memory>
 #include <vector>
 
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.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/fxfa/fxfa.h"
 #include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
 #include "xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h"
@@ -21,35 +24,43 @@
 class CXFA_FFDocView;
 class CXFA_TabParam;
 
-class CXFA_FFPageView : public Observable {
+class CXFA_FFPageView final : public cppgc::GarbageCollected<CXFA_FFPageView>,
+                              public Observable {
  public:
-  CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFPageView();
 
-  CXFA_ViewLayoutItem* GetLayoutItem() const { return m_pLayoutItem.Get(); }
+  void Trace(cppgc::Visitor* visitor) const;
+
+  CXFA_ViewLayoutItem* GetLayoutItem() const { return m_pLayoutItem; }
   void SetLayoutItem(CXFA_ViewLayoutItem* pItem) { m_pLayoutItem = pItem; }
 
   CXFA_FFDocView* GetDocView() const;
   CFX_RectF GetPageViewRect() const;
   CFX_Matrix GetDisplayMatrix(const FX_RECT& rtDisp, int32_t iRotate) const;
 
-  // These always return a non-null iterator.
-  std::unique_ptr<IXFA_WidgetIterator> CreateFormWidgetIterator(
-      uint32_t dwWidgetFilter);
-  std::unique_ptr<IXFA_WidgetIterator> CreateTraverseWidgetIterator(
+  // These always return a non-null iterator from the gc heap.
+  IXFA_WidgetIterator* CreateGCedFormWidgetIterator(uint32_t dwWidgetFilter);
+  IXFA_WidgetIterator* CreateGCedTraverseWidgetIterator(
       uint32_t dwWidgetFilter);
 
  private:
-  UnownedPtr<CXFA_Node> const m_pPageArea;
-  UnownedPtr<CXFA_FFDocView> const m_pDocView;
-  UnownedPtr<CXFA_ViewLayoutItem> m_pLayoutItem;
+  CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea);
+
+  cppgc::Member<CXFA_Node> const m_pPageArea;
+  cppgc::Member<CXFA_FFDocView> const m_pDocView;
+  cppgc::Member<CXFA_ViewLayoutItem> m_pLayoutItem;
 };
 
-class CXFA_FFPageWidgetIterator final : public IXFA_WidgetIterator {
+class CXFA_FFPageWidgetIterator final
+    : public cppgc::GarbageCollected<CXFA_FFPageWidgetIterator>,
+      public IXFA_WidgetIterator {
  public:
-  CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, uint32_t dwFilter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFPageWidgetIterator() override;
 
+  void Trace(cppgc::Visitor* visitor) const {}
+
   void Reset() override;
   CXFA_FFWidget* MoveToFirst() override;
   CXFA_FFWidget* MoveToLast() override;
@@ -59,6 +70,8 @@
   bool SetCurrentWidget(CXFA_FFWidget* hWidget) override;
 
  private:
+  CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, uint32_t dwFilter);
+
   CXFA_FFWidget* GetWidget(CXFA_LayoutItem* pLayoutItem);
 
   CXFA_LayoutItemIterator m_sIterator;
@@ -66,12 +79,15 @@
   const bool m_bIgnoreRelevant;
 };
 
-class CXFA_FFTabOrderPageWidgetIterator final : public IXFA_WidgetIterator {
+class CXFA_FFTabOrderPageWidgetIterator final
+    : public cppgc::GarbageCollected<CXFA_FFPageWidgetIterator>,
+      public IXFA_WidgetIterator {
  public:
-  CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView,
-                                    uint32_t dwFilter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFTabOrderPageWidgetIterator() override;
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   void Reset() override;
   CXFA_FFWidget* MoveToFirst() override;
   CXFA_FFWidget* MoveToLast() override;
@@ -81,11 +97,14 @@
   bool SetCurrentWidget(CXFA_FFWidget* hWidget) override;
 
  private:
+  CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView,
+                                    uint32_t dwFilter);
+
   CXFA_FFWidget* GetTraverseWidget(CXFA_FFWidget* pWidget);
   CXFA_FFWidget* FindWidgetByName(const WideString& wsWidgetName,
                                   CXFA_FFWidget* pRefWidget);
   void CreateTabOrderWidgetArray();
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> CreateSpaceOrderLayoutItems();
+  std::vector<CXFA_ContentLayoutItem*> CreateSpaceOrderLayoutItems();
   CXFA_FFWidget* GetWidget(CXFA_LayoutItem* pLayoutItem);
   void OrderContainer(CXFA_LayoutItemIterator* sIterator,
                       CXFA_LayoutItem* pViewItem,
@@ -94,8 +113,8 @@
                       bool* bContentArea,
                       bool bMasterPage);
 
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> m_TabOrderWidgetArray;
-  RetainPtr<CXFA_ViewLayoutItem> const m_pPageViewLayout;
+  cppgc::Member<CXFA_ViewLayoutItem> const m_pPageViewLayout;
+  std::vector<cppgc::Member<CXFA_ContentLayoutItem>> m_TabOrderWidgetArray;
   const uint32_t m_dwFilter;
   int32_t m_iCurWidget = -1;
   const bool m_bIgnoreRelevant;
diff --git a/xfa/fxfa/cxfa_ffpasswordedit.cpp b/xfa/fxfa/cxfa_ffpasswordedit.cpp
index 0c25a06..87f17c9 100644
--- a/xfa/fxfa/cxfa_ffpasswordedit.cpp
+++ b/xfa/fxfa/cxfa_ffpasswordedit.cpp
@@ -21,12 +21,14 @@
 
 CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() = default;
 
+void CXFA_FFPasswordEdit::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFTextEdit::Trace(visitor);
+  visitor->Trace(password_node_);
+}
+
 bool CXFA_FFPasswordEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNewEdit = std::make_unique<CFWL_Edit>(
       GetFWLApp(), CFWL_Widget::Properties(), nullptr);
   CFWL_Edit* pWidget = pNewEdit.get();
diff --git a/xfa/fxfa/cxfa_ffpasswordedit.h b/xfa/fxfa/cxfa_ffpasswordedit.h
index a96efa0..f09d245 100644
--- a/xfa/fxfa/cxfa_ffpasswordedit.h
+++ b/xfa/fxfa/cxfa_ffpasswordedit.h
@@ -8,21 +8,28 @@
 #define XFA_FXFA_CXFA_FFPASSWORDEDIT_H_
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_fftextedit.h"
 
 class CXFA_PasswordEdit;
 
 class CXFA_FFPasswordEdit final : public CXFA_FFTextEdit {
  public:
-  CXFA_FFPasswordEdit(CXFA_Node* pNode, CXFA_PasswordEdit* password_node);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFPasswordEdit() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_FFTextEdit
   bool LoadWidget() override;
   void UpdateWidgetProperty() override;
 
  private:
-  UnownedPtr<CXFA_PasswordEdit> const password_node_;
+  CXFA_FFPasswordEdit(CXFA_Node* pNode, CXFA_PasswordEdit* password_node);
+
+  cppgc::Member<CXFA_PasswordEdit> const password_node_;
 };
 
 #endif  // XFA_FXFA_CXFA_FFPASSWORDEDIT_H_
diff --git a/xfa/fxfa/cxfa_ffpushbutton.cpp b/xfa/fxfa/cxfa_ffpushbutton.cpp
index 8957bae..793eca2 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.cpp
+++ b/xfa/fxfa/cxfa_ffpushbutton.cpp
@@ -12,6 +12,7 @@
 #include "xfa/fwl/cfwl_pushbutton.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
+#include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
@@ -29,6 +30,15 @@
 
 CXFA_FFPushButton::~CXFA_FFPushButton() = default;
 
+void CXFA_FFPushButton::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFField::Trace(visitor);
+  visitor->Trace(m_pRolloverTextLayout);
+  visitor->Trace(m_pDownTextLayout);
+  visitor->Trace(m_pRollProvider);
+  visitor->Trace(m_pDownProvider);
+  visitor->Trace(button_);
+}
+
 void CXFA_FFPushButton::RenderWidget(CXFA_Graphics* pGS,
                                      const CFX_Matrix& matrix,
                                      HighlightOption highlight) {
@@ -50,9 +60,6 @@
 bool CXFA_FFPushButton::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNew = std::make_unique<CFWL_PushButton>(GetFWLApp());
   CFWL_PushButton* pPushButton = pNew.get();
   m_pOldDelegate = pPushButton->GetDelegate();
@@ -136,20 +143,21 @@
 
   if (m_pNode->HasButtonRollover()) {
     if (!m_pRollProvider) {
-      m_pRollProvider = std::make_unique<CXFA_TextProvider>(
-          m_pNode.Get(), XFA_TEXTPROVIDERTYPE_Rollover);
+      m_pRollProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
+          GetDoc()->GetHeap()->GetAllocationHandle(), m_pNode.Get(),
+          XFA_TEXTPROVIDERTYPE_Rollover);
     }
-    m_pRolloverTextLayout =
-        std::make_unique<CXFA_TextLayout>(GetDoc(), m_pRollProvider.get());
+    m_pRolloverTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
+        GetDoc()->GetHeap()->GetAllocationHandle(), GetDoc(), m_pRollProvider);
   }
-
   if (m_pNode->HasButtonDown()) {
     if (!m_pDownProvider) {
-      m_pDownProvider = std::make_unique<CXFA_TextProvider>(
-          m_pNode.Get(), XFA_TEXTPROVIDERTYPE_Down);
+      m_pDownProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
+          GetDoc()->GetHeap()->GetAllocationHandle(), m_pNode.Get(),
+          XFA_TEXTPROVIDERTYPE_Down);
     }
-    m_pDownTextLayout =
-        std::make_unique<CXFA_TextLayout>(GetDoc(), m_pDownProvider.get());
+    m_pDownTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
+        GetDoc()->GetHeap()->GetAllocationHandle(), GetDoc(), m_pDownProvider);
   }
 }
 
@@ -193,25 +201,16 @@
 }
 
 void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessEvent(pEvent);
   CXFA_FFField::OnProcessEvent(pEvent);
 }
 
 void CXFA_FFPushButton::OnDrawWidget(CXFA_Graphics* pGraphics,
                                      const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   auto* pWidget = GetNormalWidget();
   if (pWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) {
     if ((pWidget->GetStates() & FWL_STATE_PSB_Pressed) &&
diff --git a/xfa/fxfa/cxfa_ffpushbutton.h b/xfa/fxfa/cxfa_ffpushbutton.h
index e4b34b5..207c3dc 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.h
+++ b/xfa/fxfa/cxfa_ffpushbutton.h
@@ -7,9 +7,9 @@
 #ifndef XFA_FXFA_CXFA_FFPUSHBUTTON_H_
 #define XFA_FXFA_CXFA_FFPUSHBUTTON_H_
 
-#include <memory>
-
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 
 #define XFA_FWL_PSBSTYLEEXT_HiliteInverted (1L << 0)
@@ -22,9 +22,11 @@
 
 class CXFA_FFPushButton final : public CXFA_FFField {
  public:
-  CXFA_FFPushButton(CXFA_Node* pNode, CXFA_Button* button);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFPushButton() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_FFField
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
@@ -39,6 +41,8 @@
   FormFieldType GetFormFieldType() override;
 
  private:
+  CXFA_FFPushButton(CXFA_Node* pNode, CXFA_Button* button);
+
   void LoadHighlightCaption();
   void LayoutHighlightCaption();
   void RenderHighlightCaption(CXFA_Graphics* pGS, CFX_Matrix* pMatrix);
@@ -46,12 +50,12 @@
   FX_ARGB GetLineColor();
   FX_ARGB GetFillColor();
 
-  std::unique_ptr<CXFA_TextLayout> m_pRolloverTextLayout;
-  std::unique_ptr<CXFA_TextLayout> m_pDownTextLayout;
-  std::unique_ptr<CXFA_TextProvider> m_pRollProvider;
-  std::unique_ptr<CXFA_TextProvider> m_pDownProvider;
+  cppgc::Member<CXFA_TextLayout> m_pRolloverTextLayout;
+  cppgc::Member<CXFA_TextLayout> m_pDownTextLayout;
+  cppgc::Member<CXFA_TextProvider> m_pRollProvider;
+  cppgc::Member<CXFA_TextProvider> m_pDownProvider;
   UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
-  UnownedPtr<CXFA_Button> const button_;
+  cppgc::Member<CXFA_Button> const button_;
 };
 
 #endif  // XFA_FXFA_CXFA_FFPUSHBUTTON_H_
diff --git a/xfa/fxfa/cxfa_ffrectangle.h b/xfa/fxfa/cxfa_ffrectangle.h
index d78d5ff..20cc5ad 100644
--- a/xfa/fxfa/cxfa_ffrectangle.h
+++ b/xfa/fxfa/cxfa_ffrectangle.h
@@ -11,13 +11,16 @@
 
 class CXFA_FFRectangle final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFRectangle(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFRectangle() override;
 
   // CXFA_FFWidget
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
                     HighlightOption highlight) override;
+
+ private:
+  explicit CXFA_FFRectangle(CXFA_Node* pNode);
 };
 
 #endif  // XFA_FXFA_CXFA_FFRECTANGLE_H_
diff --git a/xfa/fxfa/cxfa_ffsignature.cpp b/xfa/fxfa/cxfa_ffsignature.cpp
index 1f6dc10..7360375 100644
--- a/xfa/fxfa/cxfa_ffsignature.cpp
+++ b/xfa/fxfa/cxfa_ffsignature.cpp
@@ -18,10 +18,6 @@
 
 bool CXFA_FFSignature::LoadWidget() {
   ASSERT(!IsLoaded());
-
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return CXFA_FFField::LoadWidget();
 }
 
diff --git a/xfa/fxfa/cxfa_ffsignature.h b/xfa/fxfa/cxfa_ffsignature.h
index 0f6303c..77a6507 100644
--- a/xfa/fxfa/cxfa_ffsignature.h
+++ b/xfa/fxfa/cxfa_ffsignature.h
@@ -11,7 +11,7 @@
 
 class CXFA_FFSignature final : public CXFA_FFField {
  public:
-  explicit CXFA_FFSignature(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFSignature() override;
 
   // CXFA_FFField
@@ -39,6 +39,9 @@
   bool OnChar(uint32_t dwChar, uint32_t dwFlags) override;
   FWL_WidgetHit HitTest(const CFX_PointF& point) override;
   FormFieldType GetFormFieldType() override;
+
+ private:
+  explicit CXFA_FFSignature(CXFA_Node* pNode);
 };
 
 #endif  // XFA_FXFA_CXFA_FFSIGNATURE_H_
diff --git a/xfa/fxfa/cxfa_fftext.h b/xfa/fxfa/cxfa_fftext.h
index 92eafb1..e7db71b 100644
--- a/xfa/fxfa/cxfa_fftext.h
+++ b/xfa/fxfa/cxfa_fftext.h
@@ -11,7 +11,7 @@
 
 class CXFA_FFText final : public CXFA_FFWidget {
  public:
-  explicit CXFA_FFText(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFText() override;
 
   // CXFA_FFWidget
@@ -29,6 +29,8 @@
   bool PerformLayout() override;
 
  private:
+  explicit CXFA_FFText(CXFA_Node* pNode);
+
   const wchar_t* GetLinkURLAtPoint(const CFX_PointF& point);
 };
 
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 4f6ef70..eb4ee8c 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -45,9 +45,6 @@
 bool CXFA_FFTextEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   auto pNewWidget = std::make_unique<CFWL_Edit>(
       GetFWLApp(), CFWL_Widget::Properties(), nullptr);
   CFWL_Edit* pFWLEdit = pNewWidget.get();
@@ -125,9 +122,6 @@
 }
 
 bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!IsFocused()) {
     GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_Focused);
     UpdateFWLData();
@@ -142,9 +136,6 @@
 }
 
 bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!IsFocused()) {
     GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_Focused);
     UpdateFWLData();
@@ -158,9 +149,6 @@
 }
 
 bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   if (!CXFA_FFField::OnRButtonUp(dwFlags, point))
     return false;
 
@@ -169,9 +157,6 @@
 }
 
 bool CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pOldWatched(pOldWidget);
   GetLayoutItem()->ClearStatusBits(XFA_WidgetStatus_TextEditValueChanged);
   if (!IsFocused()) {
@@ -189,9 +174,6 @@
 }
 
 bool CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pNewWatched(pNewWidget);
   SendMessageToFWLWidget(
       std::make_unique<CFWL_MessageKillFocus>(nullptr, GetNormalWidget()));
@@ -281,8 +263,6 @@
   if (!pEdit)
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
   XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
   if (IsFocused())
     eType = XFA_VALUEPICTURE_Edit;
@@ -324,9 +304,6 @@
 
 void CXFA_FFTextEdit::OnTextWillChange(CFWL_Widget* pWidget,
                                        CFWL_EventTextWillChange* event) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_TextEditValueChanged);
 
   CXFA_EventParam eParam;
@@ -348,9 +325,6 @@
 }
 
 void CXFA_FFTextEdit::OnTextFull(CFWL_Widget* pWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_EventParam eParam;
   eParam.m_eType = XFA_EVENT_Full;
   eParam.m_pTarget = m_pNode.Get();
@@ -358,16 +332,10 @@
 }
 
 void CXFA_FFTextEdit::OnProcessMessage(CFWL_Message* pMessage) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnProcessMessage(pMessage);
 }
 
 void CXFA_FFTextEdit::OnProcessEvent(CFWL_Event* pEvent) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   CXFA_FFField::OnProcessEvent(pEvent);
   switch (pEvent->GetType()) {
     case CFWL_Event::Type::TextWillChange:
@@ -385,9 +353,6 @@
 
 void CXFA_FFTextEdit::OnDrawWidget(CXFA_Graphics* pGraphics,
                                    const CFX_Matrix& matrix) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
 }
 
@@ -419,58 +384,34 @@
 }
 
 bool CXFA_FFTextEdit::Undo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToEdit(GetNormalWidget())->Undo();
 }
 
 bool CXFA_FFTextEdit::Redo() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToEdit(GetNormalWidget())->Redo();
 }
 
 Optional<WideString> CXFA_FFTextEdit::Copy() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToEdit(GetNormalWidget())->Copy();
 }
 
 Optional<WideString> CXFA_FFTextEdit::Cut() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToEdit(GetNormalWidget())->Cut();
 }
 
 bool CXFA_FFTextEdit::Paste(const WideString& wsPaste) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   return ToEdit(GetNormalWidget())->Paste(wsPaste);
 }
 
 void CXFA_FFTextEdit::SelectAll() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToEdit(GetNormalWidget())->SelectAll();
 }
 
 void CXFA_FFTextEdit::Delete() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToEdit(GetNormalWidget())->ClearText();
 }
 
 void CXFA_FFTextEdit::DeSelect() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   ToEdit(GetNormalWidget())->ClearSelection();
 }
 
diff --git a/xfa/fxfa/cxfa_fftextedit.h b/xfa/fxfa/cxfa_fftextedit.h
index 47c8570..f3ad66c 100644
--- a/xfa/fxfa/cxfa_fftextedit.h
+++ b/xfa/fxfa/cxfa_fftextedit.h
@@ -21,7 +21,7 @@
 
 class CXFA_FFTextEdit : public CXFA_FFField {
  public:
-  explicit CXFA_FFTextEdit(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFTextEdit() override;
 
   // CXFA_FFField
@@ -62,6 +62,7 @@
   FormFieldType GetFormFieldType() override;
 
  protected:
+  explicit CXFA_FFTextEdit(CXFA_Node* pNode);
   uint32_t GetAlignment();
 
   UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 059affd..92d9d3c 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -231,6 +231,12 @@
 
 CXFA_FFWidget::~CXFA_FFWidget() = default;
 
+void CXFA_FFWidget::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pLayoutItem);
+  visitor->Trace(m_pNode);
+  visitor->Trace(m_pDocView);
+}
+
 const CFWL_App* CXFA_FFWidget::GetFWLApp() {
   return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
 }
@@ -312,9 +318,6 @@
 }
 
 bool CXFA_FFWidget::LoadWidget() {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retain_layout(m_pLayoutItem.Get());
-
   PerformLayout();
   return true;
 }
@@ -418,9 +421,6 @@
 }
 
 bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   CXFA_FFWidget* pParent = GetFFWidget(ToContentLayoutItem(GetParent()));
   if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
     if (!pParent->OnSetFocus(pOldWidget))
@@ -436,9 +436,6 @@
 }
 
 bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   ObservedPtr<CXFA_FFWidget> pNewWatched(pNewWidget);
   GetLayoutItem()->ClearStatusBits(XFA_WidgetStatus_Focused);
   EventKillFocus();
diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h
index 6893c81..df72e6f 100644
--- a/xfa/fxfa/cxfa_ffwidget.h
+++ b/xfa/fxfa/cxfa_ffwidget.h
@@ -13,6 +13,9 @@
 #include "core/fxcodec/fx_codec_def.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxge/cfx_graphstatedata.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/cfwl_widget.h"
@@ -66,21 +69,24 @@
   std::vector<CXFA_Node*> m_Globals;
 };
 
-class CXFA_FFWidget : public Observable, public CFWL_Widget::AdapterIface {
+class CXFA_FFWidget : public cppgc::GarbageCollected<CXFA_FFWidget>,
+                      public Observable,
+                      public CFWL_Widget::AdapterIface {
  public:
   enum FocusOption { kDoNotDrawFocus = 0, kDrawFocus };
   enum HighlightOption { kNoHighlight = 0, kHighlight };
 
-  explicit CXFA_FFWidget(CXFA_Node* pNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFWidget() override;
 
+  virtual void Trace(cppgc::Visitor* visitor) const;
+
   // CFWL_Widget::AdapterIface:
   CFX_Matrix GetRotateMatrix() override;
   void DisplayCaret(bool bVisible, const CFX_RectF* pRtAnchor) override;
   void GetBorderColorAndThickness(FX_ARGB* cr, float* fWidth) override;
 
   virtual CXFA_FFField* AsField();
-
   virtual CFX_RectF GetBBox(FocusOption focus);
   virtual void RenderWidget(CXFA_Graphics* pGS,
                             const CFX_Matrix& matrix,
@@ -174,6 +180,7 @@
                                 CXFA_FFWidgetHandler* pHandler);
 
  protected:
+  explicit CXFA_FFWidget(CXFA_Node* pNode);
   virtual bool PtInActiveRect(const CFX_PointF& point);
 
   void DrawBorder(CXFA_Graphics* pGS,
@@ -192,10 +199,10 @@
   bool IsButtonDown();
   void SetButtonDown(bool bSet);
 
-  UnownedPtr<CXFA_ContentLayoutItem> m_pLayoutItem;
-  UnownedPtr<CXFA_FFDocView> m_pDocView;
+  cppgc::Member<CXFA_ContentLayoutItem> m_pLayoutItem;
+  cppgc::Member<CXFA_FFDocView> m_pDocView;
   ObservedPtr<CXFA_FFPageView> m_pPageView;
-  UnownedPtr<CXFA_Node> const m_pNode;
+  cppgc::Member<CXFA_Node> const m_pNode;
   mutable CFX_RectF m_WidgetRect;
 };
 
diff --git a/xfa/fxfa/cxfa_ffwidgethandler.cpp b/xfa/fxfa/cxfa_ffwidgethandler.cpp
index 6c6d6ef..73f2a06 100644
--- a/xfa/fxfa/cxfa_ffwidgethandler.cpp
+++ b/xfa/fxfa/cxfa_ffwidgethandler.cpp
@@ -25,6 +25,10 @@
 
 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() = default;
 
+void CXFA_FFWidgetHandler::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDocView);
+}
+
 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
   m_pDocView->LockUpdate();
   bool bRet = hWidget->OnMouseEnter();
@@ -44,9 +48,6 @@
 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
                                          uint32_t dwFlags,
                                          const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |hWidget|.
-  RetainPtr<CXFA_LayoutItem> retainer(hWidget->GetLayoutItem());
-
   m_pDocView->LockUpdate();
   bool bRet = hWidget->AcceptsFocusOnButtonDown(
       dwFlags, hWidget->Rotate2Normal(point), FWL_MouseCommand::LeftButtonDown);
@@ -96,9 +97,6 @@
 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
                                          uint32_t dwFlags,
                                          const CFX_PointF& point) {
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |hWidget|.
-  RetainPtr<CXFA_LayoutItem> retainer(hWidget->GetLayoutItem());
-
   if (!hWidget->AcceptsFocusOnButtonDown(dwFlags, hWidget->Rotate2Normal(point),
                                          FWL_MouseCommand::RightButtonDown)) {
     return false;
diff --git a/xfa/fxfa/cxfa_ffwidgethandler.h b/xfa/fxfa/cxfa_ffwidgethandler.h
index 778cc10..349c9a8 100644
--- a/xfa/fxfa/cxfa_ffwidgethandler.h
+++ b/xfa/fxfa/cxfa_ffwidgethandler.h
@@ -8,6 +8,10 @@
 #define XFA_FXFA_CXFA_FFWIDGETHANDLER_H_
 
 #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 "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
@@ -16,11 +20,14 @@
 class CXFA_Graphics;
 enum class FWL_WidgetHit;
 
-class CXFA_FFWidgetHandler {
+class CXFA_FFWidgetHandler final
+    : public cppgc::GarbageCollected<CXFA_FFWidgetHandler> {
  public:
-  explicit CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFWidgetHandler();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   bool OnMouseEnter(CXFA_FFWidget* hWidget);
   bool OnMouseExit(CXFA_FFWidget* hWidget);
   bool OnLButtonDown(CXFA_FFWidget* hWidget,
@@ -71,7 +78,9 @@
   XFA_EventError ProcessEvent(CXFA_Node* pNode, CXFA_EventParam* pParam);
 
  private:
-  UnownedPtr<CXFA_FFDocView> m_pDocView;
+  explicit CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView);
+
+  cppgc::Member<CXFA_FFDocView> m_pDocView;
 };
 
 #endif  //  XFA_FXFA_CXFA_FFWIDGETHANDLER_H_
diff --git a/xfa/fxfa/cxfa_readynodeiterator.h b/xfa/fxfa/cxfa_readynodeiterator.h
index d3cd901..000c0e6 100644
--- a/xfa/fxfa/cxfa_readynodeiterator.h
+++ b/xfa/fxfa/cxfa_readynodeiterator.h
@@ -8,6 +8,7 @@
 #define XFA_FXFA_CXFA_READYNODEITERATOR_H_
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h"
 
 class CXFA_Node;
@@ -22,7 +23,7 @@
 
  private:
   CXFA_ContainerIterator m_ContentIterator;
-  UnownedPtr<CXFA_Node> m_pCurNode;
+  cppgc::Persistent<CXFA_Node> m_pCurNode;
 };
 
 #endif  // XFA_FXFA_CXFA_READYNODEITERATOR_H_
diff --git a/xfa/fxfa/cxfa_textlayout.cpp b/xfa/fxfa/cxfa_textlayout.cpp
index a0708ec..23b5083 100644
--- a/xfa/fxfa/cxfa_textlayout.cpp
+++ b/xfa/fxfa/cxfa_textlayout.cpp
@@ -26,6 +26,7 @@
 #include "xfa/fgas/layout/cfx_linkuserdata.h"
 #include "xfa/fgas/layout/cfx_rtfbreak.h"
 #include "xfa/fgas/layout/cfx_textuserdata.h"
+#include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_loadercontext.h"
 #include "xfa/fxfa/cxfa_pieceline.h"
 #include "xfa/fxfa/cxfa_textparsecontext.h"
@@ -77,6 +78,12 @@
   Unload();
 }
 
+void CXFA_TextLayout::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDoc);
+  visitor->Trace(m_pTextProvider);
+  visitor->Trace(m_pTextDataNode);
+}
+
 void CXFA_TextLayout::Unload() {
   m_pieceLines.clear();
   m_pBreak.reset();
diff --git a/xfa/fxfa/cxfa_textlayout.h b/xfa/fxfa/cxfa_textlayout.h
index e5750a0..b8cdd78 100644
--- a/xfa/fxfa/cxfa_textlayout.h
+++ b/xfa/fxfa/cxfa_textlayout.h
@@ -13,6 +13,10 @@
 #include "core/fxcrt/css/cfx_css.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_string.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/fgas/layout/cfx_char.h"
 #include "xfa/fxfa/cxfa_textparser.h"
 
@@ -31,11 +35,13 @@
 struct CXFA_LoaderContext;
 struct FX_RTFTEXTOBJ;
 
-class CXFA_TextLayout {
+class CXFA_TextLayout final : public cppgc::GarbageCollected<CXFA_TextLayout> {
  public:
-  CXFA_TextLayout(CXFA_FFDoc* doc, CXFA_TextProvider* pTextProvider);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TextLayout();
 
+  void Trace(cppgc::Visitor* visitor) const;
+
   float GetLayoutHeight();
   float StartLayout(float fWidth);
   float DoLayout(float fTextHeight);
@@ -67,6 +73,8 @@
     size_t szLength;
   };
 
+  CXFA_TextLayout(CXFA_FFDoc* doc, CXFA_TextProvider* pTextProvider);
+
   void GetTextDataNode();
   CFX_XMLNode* GetXMLContainerNode();
   std::unique_ptr<CFX_RTFBreak> CreateBreak(bool bDefault);
@@ -124,9 +132,9 @@
   int32_t m_iLines = 0;
   float m_fMaxWidth = 0;
   std::vector<BlockData> m_Blocks;
-  UnownedPtr<CXFA_FFDoc> const m_pDoc;
-  CXFA_TextProvider* const m_pTextProvider;  // Raw, owned by tree node.
-  CXFA_Node* m_pTextDataNode = nullptr;      // Raw, owned by tree node.
+  cppgc::Member<CXFA_FFDoc> const m_pDoc;
+  cppgc::Member<CXFA_TextProvider> const m_pTextProvider;
+  cppgc::Member<CXFA_Node> m_pTextDataNode;
   std::unique_ptr<CFX_RTFBreak> m_pBreak;
   std::unique_ptr<CXFA_LoaderContext> m_pLoader;
   CXFA_TextParser m_textParser;
diff --git a/xfa/fxfa/cxfa_textprovider.cpp b/xfa/fxfa/cxfa_textprovider.cpp
index 97523de..a409676 100644
--- a/xfa/fxfa/cxfa_textprovider.cpp
+++ b/xfa/fxfa/cxfa_textprovider.cpp
@@ -7,7 +7,6 @@
 #include "xfa/fxfa/cxfa_textprovider.h"
 
 #include <algorithm>
-#include <memory>
 
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmlnode.h"
@@ -35,6 +34,18 @@
 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
 #include "xfa/fxfa/parser/xfa_utils.h"
 
+CXFA_TextProvider::CXFA_TextProvider(CXFA_Node* pNode,
+                                     XFA_TEXTPROVIDERTYPE eType)
+    : m_pNode(pNode), m_eType(eType) {
+  ASSERT(m_pNode);
+}
+
+CXFA_TextProvider::~CXFA_TextProvider() = default;
+
+void CXFA_TextProvider::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pNode);
+}
+
 CXFA_Node* CXFA_TextProvider::GetTextNode(bool* bRichText) {
   *bRichText = false;
   if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
diff --git a/xfa/fxfa/cxfa_textprovider.h b/xfa/fxfa/cxfa_textprovider.h
index b4a9664..e0aae86 100644
--- a/xfa/fxfa/cxfa_textprovider.h
+++ b/xfa/fxfa/cxfa_textprovider.h
@@ -8,7 +8,11 @@
 #define XFA_FXFA_CXFA_TEXTPROVIDER_H_
 
 #include "core/fxcrt/fx_string.h"
+#include "fxjs/gc/heap.h"
 #include "third_party/base/optional.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_textlayout.h"
 
 class CXFA_Font;
@@ -23,13 +27,12 @@
   XFA_TEXTPROVIDERTYPE_Down,
 };
 
-class CXFA_TextProvider {
+class CXFA_TextProvider : public cppgc::GarbageCollected<CXFA_TextProvider> {
  public:
-  CXFA_TextProvider(CXFA_Node* pNode, XFA_TEXTPROVIDERTYPE eType)
-      : m_pNode(pNode), m_eType(eType) {
-    ASSERT(m_pNode);
-  }
-  ~CXFA_TextProvider() {}
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+  ~CXFA_TextProvider();
+
+  void Trace(cppgc::Visitor* visitor) const;
 
   CXFA_Node* GetTextNode(bool* bRichText);
   CXFA_Para* GetParaIfExists();
@@ -38,7 +41,9 @@
   Optional<WideString> GetEmbeddedObj(const WideString& wsAttr) const;
 
  private:
-  CXFA_Node* m_pNode;  // Raw, this class owned by tree node.
+  CXFA_TextProvider(CXFA_Node* pNode, XFA_TEXTPROVIDERTYPE eType);
+
+  cppgc::Member<CXFA_Node> m_pNode;
   XFA_TEXTPROVIDERTYPE m_eType;
 };
 
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutitem.cpp b/xfa/fxfa/layout/cxfa_contentlayoutitem.cpp
index 250cd57..01410c95 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutitem.cpp
+++ b/xfa/fxfa/layout/cxfa_contentlayoutitem.cpp
@@ -13,19 +13,20 @@
 #include "xfa/fxfa/parser/cxfa_margin.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 
-CXFA_ContentLayoutItem::CXFA_ContentLayoutItem(
-    CXFA_Node* pNode,
-    std::unique_ptr<CXFA_FFWidget> pWidget)
-    : CXFA_LayoutItem(pNode, kContentItem), m_pFFWidget(std::move(pWidget)) {
+CXFA_ContentLayoutItem::CXFA_ContentLayoutItem(CXFA_Node* pNode,
+                                               CXFA_FFWidget* pWidget)
+    : CXFA_LayoutItem(pNode, kContentItem), m_pFFWidget(pWidget) {
   if (m_pFFWidget)
     m_pFFWidget->SetLayoutItem(this);
 }
 
-CXFA_ContentLayoutItem::~CXFA_ContentLayoutItem() {
-  if (m_pFFWidget)
-    m_pFFWidget->SetLayoutItem(nullptr);
+CXFA_ContentLayoutItem::~CXFA_ContentLayoutItem() = default;
 
-  RemoveSelf();
+void CXFA_ContentLayoutItem::Trace(cppgc::Visitor* visitor) const {
+  CXFA_LayoutItem::Trace(visitor);
+  visitor->Trace(m_pPrev);
+  visitor->Trace(m_pNext);
+  visitor->Trace(m_pFFWidget);
 }
 
 CXFA_ContentLayoutItem* CXFA_ContentLayoutItem::GetFirst() {
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutitem.h b/xfa/fxfa/layout/cxfa_contentlayoutitem.h
index 8b29a7a..debd780 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutitem.h
+++ b/xfa/fxfa/layout/cxfa_contentlayoutitem.h
@@ -7,21 +7,22 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTITEM_H_
 #define XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTITEM_H_
 
-#include <memory>
-
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
 
 class CXFA_FFWidget;
 
 class CXFA_ContentLayoutItem final : public CXFA_LayoutItem {
  public:
-  CONSTRUCT_VIA_MAKE_RETAIN;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ContentLayoutItem() override;
 
-  CXFA_FFWidget* GetFFWidget() { return m_pFFWidget.get(); }
+  void Trace(cppgc::Visitor* visitor) const override;
+
+  CXFA_FFWidget* GetFFWidget() { return m_pFFWidget; }
 
   CXFA_ContentLayoutItem* GetFirst();
   CXFA_ContentLayoutItem* GetLast();
@@ -42,15 +43,13 @@
   CFX_SizeF m_sSize;
 
  private:
-  CXFA_ContentLayoutItem(CXFA_Node* pNode,
-                         std::unique_ptr<CXFA_FFWidget> pFFWidget);
-
+  CXFA_ContentLayoutItem(CXFA_Node* pNode, CXFA_FFWidget* pFFWidget);
   void RemoveSelf();
 
   mutable uint32_t m_dwStatus = 0;
-  UnownedPtr<CXFA_ContentLayoutItem> m_pPrev;
-  UnownedPtr<CXFA_ContentLayoutItem> m_pNext;
-  std::unique_ptr<CXFA_FFWidget> const m_pFFWidget;
+  cppgc::Member<CXFA_ContentLayoutItem> m_pPrev;
+  cppgc::Member<CXFA_ContentLayoutItem> m_pNext;
+  cppgc::Member<CXFA_FFWidget> const m_pFFWidget;
 };
 
 inline CXFA_FFWidget* GetFFWidget(CXFA_ContentLayoutItem* item) {
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
index 8f4ef77..877ab75 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
@@ -7,7 +7,6 @@
 #include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h"
 
 #include <algorithm>
-#include <memory>
 #include <utility>
 #include <vector>
 
@@ -184,7 +183,7 @@
   return inset;
 }
 
-void RelocateTableRowCells(const RetainPtr<CXFA_ContentLayoutItem>& pLayoutRow,
+void RelocateTableRowCells(CXFA_ContentLayoutItem* pLayoutRow,
                            const std::vector<float>& rgSpecifiedColumnWidths,
                            XFA_AttributeValue eLayout) {
   bool bContainerWidthAutoSize = true;
@@ -436,12 +435,12 @@
   CXFA_NodeIterator sIterator(pGenerateNode);
   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
        pNode = sIterator.MoveToNext()) {
-    RetainPtr<CXFA_ContentLayoutItem> pCurLayoutItem(
-        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem()));
+    CXFA_ContentLayoutItem* pCurLayoutItem =
+        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem());
     while (pCurLayoutItem) {
       CXFA_ContentLayoutItem* pNextLayoutItem = pCurLayoutItem->GetNext();
-      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem.Get());
-      pCurLayoutItem.Reset(pNextLayoutItem);
+      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
+      pCurLayoutItem = pNextLayoutItem;
     }
   }
   pGenerateNode->GetParent()->RemoveChildAndNotify(pGenerateNode, true);
@@ -617,38 +616,55 @@
 }  // namespace
 
 CXFA_ContentLayoutProcessor::CXFA_ContentLayoutProcessor(
+    cppgc::Heap* pHeap,
     CXFA_Node* pNode,
     CXFA_ViewLayoutProcessor* pViewLayoutProcessor)
-    : m_pFormNode(pNode), m_pViewLayoutProcessor(pViewLayoutProcessor) {
+    : m_pHeap(pHeap),
+      m_pFormNode(pNode),
+      m_pViewLayoutProcessor(pViewLayoutProcessor) {
   ASSERT(GetFormNode());
   ASSERT(GetFormNode()->IsContainerNode() ||
          GetFormNode()->GetElementType() == XFA_Element::Form);
-  m_pOldLayoutItem.Reset(
-      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem()));
+  m_pOldLayoutItem =
+      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem());
 }
 
 CXFA_ContentLayoutProcessor::~CXFA_ContentLayoutProcessor() = default;
 
-RetainPtr<CXFA_ContentLayoutItem>
-CXFA_ContentLayoutProcessor::CreateContentLayoutItem(CXFA_Node* pFormNode) {
+void CXFA_ContentLayoutProcessor::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pFormNode);
+  visitor->Trace(m_pCurChildNode);
+  visitor->Trace(m_pKeepHeadNode);
+  visitor->Trace(m_pKeepTailNode);
+  visitor->Trace(m_pCurChildPreprocessor);
+  visitor->Trace(m_pLayoutItem);
+  visitor->Trace(m_pOldLayoutItem);
+  visitor->Trace(m_pViewLayoutProcessor);
+  for (const auto& item : m_ArrayKeepItems)
+    visitor->Trace(item);
+}
+
+CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::CreateContentLayoutItem(
+    CXFA_Node* pFormNode) {
   if (!pFormNode)
     return nullptr;
 
   if (m_pOldLayoutItem) {
-    RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pOldLayoutItem;
-    m_pOldLayoutItem.Reset(m_pOldLayoutItem->GetNext());
+    CXFA_ContentLayoutItem* pLayoutItem = m_pOldLayoutItem;
+    m_pOldLayoutItem = m_pOldLayoutItem->GetNext();
     return pLayoutItem;
   }
   CXFA_FFNotify* pNotify = pFormNode->GetDocument()->GetNotify();
-  auto pNewLayoutItem = pdfium::MakeRetain<CXFA_ContentLayoutItem>(
-      pFormNode, pNotify->OnCreateContentLayoutItem(pFormNode));
+  auto* pNewLayoutItem = cppgc::MakeGarbageCollected<CXFA_ContentLayoutItem>(
+      GetHeap()->GetAllocationHandle(), pFormNode,
+      pNotify->OnCreateContentLayoutItem(pFormNode));
 
   CXFA_ContentLayoutItem* pPrevLayoutItem =
       ToContentLayoutItem(pFormNode->JSObject()->GetLayoutItem());
   if (pPrevLayoutItem) {
-    pPrevLayoutItem->GetLast()->InsertAfter(pNewLayoutItem.Get());
+    pPrevLayoutItem->GetLast()->InsertAfter(pNewLayoutItem);
   } else {
-    pFormNode->JSObject()->SetLayoutItem(pNewLayoutItem.Get());
+    pFormNode->JSObject()->SetLayoutItem(pNewLayoutItem);
   }
   return pNewLayoutItem;
 }
@@ -690,7 +706,7 @@
         XFA_Attribute::BottomInset, XFA_Unit::Pt);
   }
 
-  RetainPtr<CXFA_ContentLayoutItem> pSecondLayoutItem;
+  CXFA_ContentLayoutItem* pSecondLayoutItem = nullptr;
   if (m_pCurChildPreprocessor &&
       m_pCurChildPreprocessor->GetFormNode() == pLayoutItem->GetFormNode()) {
     pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
@@ -731,16 +747,16 @@
     bOrphanedItem = true;
   }
 
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> children;
+  std::vector<CXFA_ContentLayoutItem*> children;
   while (auto* pFirst = ToContentLayoutItem(pLayoutItem->GetFirstChild())) {
-    children.emplace_back(pFirst);
+    children.push_back(pFirst);
     pLayoutItem->RemoveChild(children.back());
   }
 
   float lHeightForKeep = 0;
   float fAddMarginHeight = 0;
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
-  for (auto& pChildItem : children) {
+  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
+  for (CXFA_ContentLayoutItem* pChildItem : children) {
     if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                          kXFALayoutPrecision) {
       if (!ExistContainerKeep(pChildItem->GetFormNode(), true)) {
@@ -751,7 +767,7 @@
         continue;
       }
       if (lHeightForKeep < kXFALayoutPrecision) {
-        for (auto& pPreItem : keepLayoutItems) {
+        for (CXFA_ContentLayoutItem* pPreItem : keepLayoutItems) {
           pLayoutItem->RemoveChild(pPreItem);
           pPreItem->m_sPos.y -= fSplitPos;
           if (pPreItem->m_sPos.y < 0)
@@ -785,7 +801,7 @@
 
     float fOldHeight = pSecondLayoutItem->m_sSize.height;
     SplitLayoutItem(
-        pChildItem.Get(), pSecondLayoutItem.Get(),
+        pChildItem, pSecondLayoutItem,
         fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
     fAddMarginHeight = pSecondLayoutItem->m_sSize.height - fOldHeight;
     pLayoutItem->AppendLastChild(pChildItem);
@@ -799,11 +815,10 @@
   SplitLayoutItem(m_pLayoutItem.Get(), nullptr, fSplitPos);
 }
 
-RetainPtr<CXFA_ContentLayoutItem>
-CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
-  RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pLayoutItem;
+CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
+  CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
   if (pLayoutItem) {
-    m_pLayoutItem.Reset(ToContentLayoutItem(pLayoutItem->GetNextSibling()));
+    m_pLayoutItem = ToContentLayoutItem(pLayoutItem->GetNextSibling());
     pLayoutItem->RemoveSelfIfParented();
   }
   if (m_nCurChildNodeStage != Stage::kDone || !m_pOldLayoutItem)
@@ -815,11 +830,11 @@
       m_pOldLayoutItem->GetFormNode()->GetDocument());
 
   while (m_pOldLayoutItem) {
-    RetainPtr<CXFA_ContentLayoutItem> pToDeleteItem = m_pOldLayoutItem;
-    m_pOldLayoutItem.Reset(pToDeleteItem->GetNext());
+    CXFA_ContentLayoutItem* pToDeleteItem = m_pOldLayoutItem;
+    m_pOldLayoutItem = pToDeleteItem->GetNext();
     if (pToDeleteItem == pLayoutItem)
       break;
-    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem.Get());
+    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem);
     pToDeleteItem->RemoveSelfIfParented();
   }
   return pLayoutItem;
@@ -982,8 +997,8 @@
         pCurChildNode->GetElementType() == XFA_Element::Variables)
       continue;
 
-    auto pProcessor =
-        std::make_unique<CXFA_ContentLayoutProcessor>(pCurChildNode, nullptr);
+    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+        GetHeap()->GetAllocationHandle(), GetHeap(), pCurChildNode, nullptr);
     pProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
     if (!pProcessor->HasLayoutItem())
       continue;
@@ -991,21 +1006,21 @@
     pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos(
         pCurChildNode, pProcessor->GetCurrentComponentSize()));
 
-    RetainPtr<CXFA_LayoutItem> pProcessItem = pProcessor->ExtractLayoutItem();
+    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
     if (!pBeforeItem)
       pPageAreaLayoutItem->AppendFirstChild(pProcessItem);
     else
       pPageAreaLayoutItem->InsertAfter(pProcessItem, pBeforeItem);
 
-    pBeforeItem = pProcessItem.Get();
+    pBeforeItem = pProcessItem;
   }
 
   pBeforeItem = nullptr;
-  RetainPtr<CXFA_LayoutItem> pLayoutItem(pPageAreaLayoutItem->GetFirstChild());
+  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->GetFirstChild();
   while (pLayoutItem) {
     if (!pLayoutItem->IsContentLayoutItem() ||
         pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw) {
-      pLayoutItem.Reset(pLayoutItem->GetNextSibling());
+      pLayoutItem = pLayoutItem->GetNextSibling();
       continue;
     }
     if (pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw)
@@ -1018,8 +1033,8 @@
     else
       pPageAreaLayoutItem->InsertAfter(pLayoutItem, pBeforeItem);
 
-    pBeforeItem = pLayoutItem.Get();
-    pLayoutItem.Reset(pNextLayoutItem);
+    pBeforeItem = pLayoutItem;
+    pLayoutItem = pNextLayoutItem;
   }
 }
 
@@ -1051,8 +1066,10 @@
     if (m_pCurChildNode->GetElementType() == XFA_Element::Variables)
       continue;
 
-    auto pProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-        m_pCurChildNode, m_pViewLayoutProcessor.Get());
+    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+        GetHeap()->GetAllocationHandle(), GetHeap(), m_pCurChildNode,
+        m_pViewLayoutProcessor);
+
     if (pContext && pContext->m_prgSpecifiedColumnWidths) {
       int32_t iColSpan =
           m_pCurChildNode->JSObject()->GetInteger(XFA_Attribute::ColSpan);
@@ -1186,8 +1203,10 @@
     if (m_nCurChildNodeStage != Stage::kContainer)
       continue;
 
-    auto pProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-        m_pCurChildNode, m_pViewLayoutProcessor.Get());
+    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+        GetHeap()->GetAllocationHandle(), GetHeap(), m_pCurChildNode,
+        m_pViewLayoutProcessor);
+
     pProcessor->DoLayoutInternal(false, FLT_MAX, FLT_MAX, pLayoutContext);
     if (!pProcessor->HasLayoutItem())
       continue;
@@ -1296,8 +1315,7 @@
   float fCurrentRowY = 0;
   for (CXFA_LayoutItem* pIter = m_pLayoutItem->GetFirstChild(); pIter;
        pIter = pIter->GetNextSibling()) {
-    RetainPtr<CXFA_ContentLayoutItem> pLayoutChild(
-        pIter->AsContentLayoutItem());
+    CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
     if (!pLayoutChild || !pLayoutChild->GetFormNode()->PresenceRequiresSpace())
       continue;
 
@@ -1376,8 +1394,7 @@
   }
 
   float fTotalHeight = 0;
-  for (const RetainPtr<CXFA_ContentLayoutItem>& item :
-       pdfium::base::Reversed(m_ArrayKeepItems)) {
+  for (const auto& item : pdfium::base::Reversed(m_ArrayKeepItems)) {
     AddLeaderAfterSplit(item);
     fTotalHeight += item->m_sSize.height;
   }
@@ -1389,7 +1406,7 @@
 bool CXFA_ContentLayoutProcessor::ProcessKeepForSplit(
     CXFA_ContentLayoutProcessor* pChildProcessor,
     Result eRetValue,
-    std::vector<RetainPtr<CXFA_ContentLayoutItem>>* rgCurLineLayoutItem,
+    std::vector<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem,
     float* fContentCurRowAvailWidth,
     float* fContentCurRowHeight,
     float* fContentCurRowY,
@@ -1407,11 +1424,11 @@
     return false;
 
   CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize();
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
+  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
   if (JudgePutNextPage(m_pLayoutItem.Get(), childSize.height,
                        &keepLayoutItems)) {
     m_ArrayKeepItems.clear();
-    for (auto& item : keepLayoutItems) {
+    for (CXFA_ContentLayoutItem* item : keepLayoutItems) {
       m_pLayoutItem->RemoveChild(item);
       *fContentCurRowY -= item->m_sSize.height;
       m_ArrayKeepItems.push_back(item);
@@ -1433,15 +1450,14 @@
 bool CXFA_ContentLayoutProcessor::JudgePutNextPage(
     CXFA_ContentLayoutItem* pParentLayoutItem,
     float fChildHeight,
-    std::vector<RetainPtr<CXFA_ContentLayoutItem>>* pKeepItems) {
+    std::vector<CXFA_ContentLayoutItem*>* pKeepItems) {
   if (!pParentLayoutItem)
     return false;
 
   float fItemsHeight = 0;
   for (CXFA_LayoutItem* pIter = pParentLayoutItem->GetFirstChild(); pIter;
        pIter = pIter->GetNextSibling()) {
-    RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem(
-        pIter->AsContentLayoutItem());
+    CXFA_ContentLayoutItem* pChildLayoutItem = pIter->AsContentLayoutItem();
     if (!pChildLayoutItem)
       continue;
 
@@ -1478,7 +1494,7 @@
 void CXFA_ContentLayoutProcessor::ProcessUnUseOverFlow(
     CXFA_Node* pLeaderNode,
     CXFA_Node* pTrailerNode,
-    const RetainPtr<CXFA_ContentLayoutItem>& pTrailerItem,
+    CXFA_ContentLayoutItem* pTrailerItem,
     CXFA_Node* pFormNode) {
   ProcessUnUseBinds(pLeaderNode);
   ProcessUnUseBinds(pTrailerNode);
@@ -1558,7 +1574,7 @@
     float fContentCurRowHeight = 0;
     float fContentCurRowAvailWidth = fContentWidthLimit;
     m_fWidthLimit = fContentCurRowAvailWidth;
-    std::vector<RetainPtr<CXFA_ContentLayoutItem>> rgCurLineLayoutItems[3];
+    std::vector<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3];
     uint8_t uCurHAlignState =
         (eFlowStrategy != XFA_AttributeValue::Rl_tb ? 0 : 2);
     if (pLastChild) {
@@ -1575,7 +1591,7 @@
             pLayoutNext->InsertAfter(
                 m_pCurChildPreprocessor->m_pLayoutItem.Get());
           }
-          m_pCurChildPreprocessor->m_pLayoutItem.Reset(pLayoutNext);
+          m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
           break;
         }
         uint8_t uHAlign =
@@ -1595,18 +1611,18 @@
         }
       }
 
-      RetainPtr<CXFA_ContentLayoutItem> pLayoutNextTemp(pLastChild);
+      CXFA_ContentLayoutItem* pLayoutNextTemp = pLastChild;
       while (pLayoutNextTemp) {
         CXFA_ContentLayoutItem* pSaveLayoutNext =
             ToContentLayoutItem(pLayoutNextTemp->GetNextSibling());
         pLayoutNextTemp->RemoveSelfIfParented();
-        pLayoutNextTemp.Reset(pSaveLayoutNext);
+        pLayoutNextTemp = pSaveLayoutNext;
       }
       pLastChild = nullptr;
     }
 
     while (m_pCurChildNode) {
-      std::unique_ptr<CXFA_ContentLayoutProcessor> pProcessor;
+      CXFA_ContentLayoutProcessor* pProcessor = nullptr;
       bool bAddedItemInRow = false;
       fContentCurRowY += InsertPendingItems(GetFormNode());
       switch (m_nCurChildNodeStage) {
@@ -1640,11 +1656,13 @@
                 !m_pLayoutItem) {
               AddPendingNode(pTrailerNode, true);
             } else {
-              auto pTempProcessor =
-                  std::make_unique<CXFA_ContentLayoutProcessor>(pTrailerNode,
-                                                                nullptr);
+              auto* pTempProcessor =
+                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                      GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
+                      nullptr);
+
               InsertFlowedItem(
-                  pTempProcessor.get(), bContainerWidthAutoSize,
+                  pTempProcessor, bContainerWidthAutoSize,
                   bContainerHeightAutoSize, container_size.height,
                   eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                   FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
@@ -1672,9 +1690,12 @@
           CXFA_Node* pTrailerNode = break_data.value().pTrailer;
           bool bCreatePage = break_data.value().bCreatePage;
           if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
-            auto pTempProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-                pTrailerNode, nullptr);
-            InsertFlowedItem(pTempProcessor.get(), bContainerWidthAutoSize,
+            auto* pTempProcessor =
+                cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                    GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
+                    nullptr);
+
+            InsertFlowedItem(pTempProcessor, bContainerWidthAutoSize,
                              bContainerHeightAutoSize, container_size.height,
                              eFlowStrategy, &uCurHAlignState,
                              rgCurLineLayoutItems, false, FLT_MAX, FLT_MAX,
@@ -1690,11 +1711,12 @@
                   &calculated_size.height, &fContentCurRowY,
                   fContentCurRowHeight, fContentWidthLimit, false);
               rgCurLineLayoutItems->clear();
-              auto pTempProcessor =
-                  std::make_unique<CXFA_ContentLayoutProcessor>(pLeaderNode,
-                                                                nullptr);
+              auto* pTempProcessor =
+                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                      GetHeap()->GetAllocationHandle(), GetHeap(), pLeaderNode,
+                      nullptr);
               InsertFlowedItem(
-                  pTempProcessor.get(), bContainerWidthAutoSize,
+                  pTempProcessor, bContainerWidthAutoSize,
                   bContainerHeightAutoSize, container_size.height,
                   eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                   FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
@@ -1717,19 +1739,22 @@
         }
         case Stage::kBookendLeader: {
           if (m_pCurChildPreprocessor) {
-            pProcessor = std::move(m_pCurChildPreprocessor);
+            pProcessor = m_pCurChildPreprocessor.Get();
+            m_pCurChildPreprocessor = nullptr;
           } else if (m_pViewLayoutProcessor) {
             CXFA_Node* pLeaderNode =
                 m_pViewLayoutProcessor->ProcessBookendLeader(m_pCurChildNode);
             if (pLeaderNode) {
-              pProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-                  pLeaderNode, m_pViewLayoutProcessor.Get());
+              pProcessor =
+                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                      GetHeap()->GetAllocationHandle(), GetHeap(), pLeaderNode,
+                      m_pViewLayoutProcessor);
             }
           }
 
           if (pProcessor) {
             if (InsertFlowedItem(
-                    pProcessor.get(), bContainerWidthAutoSize,
+                    pProcessor, bContainerWidthAutoSize,
                     bContainerHeightAutoSize, container_size.height,
                     eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                     bUseBreakControl, fAvailHeight, fRealHeight,
@@ -1739,7 +1764,7 @@
                     false) != Result::kDone) {
               goto SuspendAndCreateNewRow;
             }
-            pProcessor.reset();
+            pProcessor = nullptr;
           }
           break;
         }
@@ -1750,13 +1775,15 @@
             CXFA_Node* pTrailerNode =
                 m_pViewLayoutProcessor->ProcessBookendTrailer(m_pCurChildNode);
             if (pTrailerNode) {
-              pProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-                  pTrailerNode, m_pViewLayoutProcessor.Get());
+              pProcessor =
+                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                      GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
+                      m_pViewLayoutProcessor);
             }
           }
           if (pProcessor) {
             if (InsertFlowedItem(
-                    pProcessor.get(), bContainerWidthAutoSize,
+                    pProcessor, bContainerWidthAutoSize,
                     bContainerHeightAutoSize, container_size.height,
                     eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                     bUseBreakControl, fAvailHeight, fRealHeight,
@@ -1766,7 +1793,7 @@
                     false) != Result::kDone) {
               goto SuspendAndCreateNewRow;
             }
-            pProcessor.reset();
+            pProcessor = nullptr;
           }
           break;
         }
@@ -1787,18 +1814,20 @@
             pProcessor = std::move(m_pCurChildPreprocessor);
             bNewRow = true;
           } else {
-            pProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-                m_pCurChildNode, m_pViewLayoutProcessor.Get());
+            pProcessor =
+                cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                    GetHeap()->GetAllocationHandle(), GetHeap(),
+                    m_pCurChildNode, m_pViewLayoutProcessor);
           }
 
           pProcessor->InsertPendingItems(m_pCurChildNode);
           Result rs = InsertFlowedItem(
-              pProcessor.get(), bContainerWidthAutoSize,
-              bContainerHeightAutoSize, container_size.height, eFlowStrategy,
-              &uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
-              fAvailHeight, fRealHeight, fContentWidthLimit, &fContentCurRowY,
-              &fContentCurRowAvailWidth, &fContentCurRowHeight,
-              &bAddedItemInRow, &bForceEndPage, pContext, bNewRow);
+              pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize,
+              container_size.height, eFlowStrategy, &uCurHAlignState,
+              rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight,
+              fContentWidthLimit, &fContentCurRowY, &fContentCurRowAvailWidth,
+              &fContentCurRowHeight, &bAddedItemInRow, &bForceEndPage, pContext,
+              bNewRow);
           switch (rs) {
             case Result::kManualBreak:
               bIsManualBreak = true;
@@ -1812,7 +1841,7 @@
             default:
               fContentCurRowY +=
                   pProcessor->InsertPendingItems(m_pCurChildNode);
-              pProcessor.reset();
+              pProcessor = nullptr;
               break;
           }
           break;
@@ -1870,7 +1899,7 @@
 }
 
 bool CXFA_ContentLayoutProcessor::CalculateRowChildPosition(
-    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
+    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
     XFA_AttributeValue eFlowStrategy,
     bool bContainerHeightAutoSize,
     bool bContainerWidthAutoSize,
@@ -2131,7 +2160,7 @@
 }
 
 void CXFA_ContentLayoutProcessor::UpdatePendingItemLayout(
-    const RetainPtr<CXFA_ContentLayoutItem>& pLayoutItem) {
+    CXFA_ContentLayoutItem* pLayoutItem) {
   XFA_AttributeValue eLayout =
       pLayoutItem->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
   switch (eLayout) {
@@ -2146,7 +2175,7 @@
 
 void CXFA_ContentLayoutProcessor::AddTrailerBeforeSplit(
     float fSplitPos,
-    const RetainPtr<CXFA_ContentLayoutItem>& pTrailerLayoutItem,
+    CXFA_ContentLayoutItem* pTrailerLayoutItem,
     bool bUseInherited) {
   if (!pTrailerLayoutItem)
     return;
@@ -2165,7 +2194,7 @@
   CXFA_Margin* pMargin =
       GetFormNode()->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
   CFX_FloatRect inset = GetMarginInset(pMargin);
-  if (!IsAddNewRowForTrailer(pTrailerLayoutItem.Get())) {
+  if (!IsAddNewRowForTrailer(pTrailerLayoutItem)) {
     pTrailerLayoutItem->m_sPos.y = m_fLastRowY;
     pTrailerLayoutItem->m_sPos.x = m_fLastRowWidth;
     m_pLayoutItem->m_sSize.width += pTrailerLayoutItem->m_sSize.width;
@@ -2207,7 +2236,7 @@
 }
 
 void CXFA_ContentLayoutProcessor::AddLeaderAfterSplit(
-    const RetainPtr<CXFA_ContentLayoutItem>& pLeaderLayoutItem) {
+    CXFA_ContentLayoutItem* pLeaderLayoutItem) {
   UpdatePendingItemLayout(pLeaderLayoutItem);
 
   CXFA_Margin* pMarginNode =
@@ -2271,11 +2300,13 @@
   }
 
   while (!m_PendingNodes.empty()) {
-    auto pPendingProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-        m_PendingNodes.front(), nullptr);
+    auto* pPendingProcessor =
+        cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+            GetHeap()->GetAllocationHandle(), GetHeap(), m_PendingNodes.front(),
+            nullptr);
     m_PendingNodes.pop_front();
     pPendingProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
-    RetainPtr<CXFA_ContentLayoutItem> pPendingLayoutItem;
+    CXFA_ContentLayoutItem* pPendingLayoutItem = nullptr;
     if (pPendingProcessor->HasLayoutItem())
       pPendingLayoutItem = pPendingProcessor->ExtractLayoutItem();
     if (pPendingLayoutItem) {
@@ -2295,7 +2326,7 @@
     float fContainerHeight,
     XFA_AttributeValue eFlowStrategy,
     uint8_t* uCurHAlignState,
-    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
+    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
     bool bUseBreakControl,
     float fAvailHeight,
     float fRealHeight,
@@ -2378,7 +2409,7 @@
   CXFA_Node* pOverflowLeaderNode = nullptr;
   CXFA_Node* pOverflowTrailerNode = nullptr;
   CXFA_Node* pFormNode = nullptr;
-  RetainPtr<CXFA_ContentLayoutItem> pTrailerLayoutItem;
+  CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr;
   bool bIsAddTrailerHeight = false;
   if (m_pViewLayoutProcessor &&
       pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
@@ -2395,8 +2426,9 @@
       pOverflowTrailerNode = overflow_data.value().pTrailer;
       if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
         if (pOverflowTrailerNode) {
-          auto pOverflowLeaderProcessor =
-              std::make_unique<CXFA_ContentLayoutProcessor>(
+          auto* pOverflowLeaderProcessor =
+              cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+                  GetHeap()->GetAllocationHandle(), GetHeap(),
                   pOverflowTrailerNode, nullptr);
           pOverflowLeaderProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
           pTrailerLayoutItem =
@@ -2407,8 +2439,8 @@
 
         bIsAddTrailerHeight =
             bUseInherited
-                ? IsAddNewRowForTrailer(pTrailerLayoutItem.Get())
-                : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem.Get());
+                ? IsAddNewRowForTrailer(pTrailerLayoutItem)
+                : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
         if (bIsAddTrailerHeight) {
           childSize.height += pTrailerLayoutItem->m_sSize.height;
           bIsAddTrailerHeight = true;
@@ -2440,7 +2472,7 @@
                                          pTrailerLayoutItem, pFormNode);
       }
 
-      RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem =
+      CXFA_ContentLayoutItem* pChildLayoutItem =
           pProcessor->ExtractLayoutItem();
       if (ExistContainerKeep(pProcessor->GetFormNode(), false) &&
           pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
index 8ba1118..cb3c101 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
@@ -11,14 +11,18 @@
 
 #include <list>
 #include <map>
-#include <memory>
 #include <utility>
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/heap.h"
 #include "third_party/base/optional.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/macros.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
 constexpr float kXFALayoutPrecision = 0.0005f;
@@ -30,7 +34,8 @@
 class CXFA_ViewLayoutItem;
 class CXFA_ViewLayoutProcessor;
 
-class CXFA_ContentLayoutProcessor {
+class CXFA_ContentLayoutProcessor
+    : public cppgc::GarbageCollected<CXFA_ContentLayoutProcessor> {
  public:
   enum class Result : uint8_t {
     kDone,
@@ -50,18 +55,22 @@
     kDone,
   };
 
-  CXFA_ContentLayoutProcessor(CXFA_Node* pNode,
-                              CXFA_ViewLayoutProcessor* pViewLayoutProcessor);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ContentLayoutProcessor();
 
+  void Trace(cppgc::Visitor* visitor) const;
+  cppgc::Heap* GetHeap() const { return m_pHeap.Get(); }
+
   Result DoLayout(bool bUseBreakControl, float fHeightLimit, float fRealHeight);
   void DoLayoutPageArea(CXFA_ViewLayoutItem* pPageAreaLayoutItem);
 
   CXFA_Node* GetFormNode() { return m_pFormNode; }
-  RetainPtr<CXFA_ContentLayoutItem> ExtractLayoutItem();
+  CXFA_ContentLayoutItem* ExtractLayoutItem();
 
  private:
   class Context {
+    CPPGC_STACK_ALLOCATED();  // Allows Raw/Unowned pointers.
+
    public:
     Context();
     ~Context();
@@ -72,6 +81,10 @@
     UnownedPtr<CXFA_Node> m_pOverflowNode;
   };
 
+  CXFA_ContentLayoutProcessor(cppgc::Heap* pHeap,
+                              CXFA_Node* pNode,
+                              CXFA_ViewLayoutProcessor* pViewLayoutProcessor);
+
   Result DoLayoutInternal(bool bUseBreakControl,
                           float fHeightLimit,
                           float fRealHeight,
@@ -84,23 +97,22 @@
   bool ProcessKeepForSplit(
       CXFA_ContentLayoutProcessor* pChildProcessor,
       Result eRetValue,
-      std::vector<RetainPtr<CXFA_ContentLayoutItem>>* rgCurLineLayoutItem,
+      std::vector<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem,
       float* fContentCurRowAvailWidth,
       float* fContentCurRowHeight,
       float* fContentCurRowY,
       bool* bAddedItemInRow,
       bool* bForceEndPage,
       Result* result);
-  void ProcessUnUseOverFlow(
-      CXFA_Node* pLeaderNode,
-      CXFA_Node* pTrailerNode,
-      const RetainPtr<CXFA_ContentLayoutItem>& pTrailerItem,
-      CXFA_Node* pFormNode);
+  void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode,
+                            CXFA_Node* pTrailerNode,
+                            CXFA_ContentLayoutItem* pTrailerItem,
+                            CXFA_Node* pFormNode);
   bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem);
   bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
 
-  RetainPtr<CXFA_ContentLayoutItem> CreateContentLayoutItem(
-      CXFA_Node* pFormNode);
+  // Object comes from GCed heap.
+  CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode);
 
   void SetCurrentComponentPos(const CFX_PointF& pos);
   void SetCurrentComponentSize(const CFX_SizeF& size);
@@ -110,7 +122,7 @@
                        float fSplitPos);
   float InsertKeepLayoutItems();
   bool CalculateRowChildPosition(
-      std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
+      std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
       XFA_AttributeValue eFlowStrategy,
       bool bContainerHeightAutoSize,
       bool bContainerWidthAutoSize,
@@ -121,10 +133,9 @@
       float fContentWidthLimit,
       bool bRootForceTb);
   void ProcessUnUseBinds(CXFA_Node* pFormNode);
-  bool JudgePutNextPage(
-      CXFA_ContentLayoutItem* pParentLayoutItem,
-      float fChildHeight,
-      std::vector<RetainPtr<CXFA_ContentLayoutItem>>* pKeepItems);
+  bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem,
+                        float fChildHeight,
+                        std::vector<CXFA_ContentLayoutItem*>* pKeepItems);
 
   void DoLayoutPositionedContainer(Context* pContext);
   void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
@@ -154,14 +165,11 @@
 
   CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
 
-  void UpdatePendingItemLayout(
-      const RetainPtr<CXFA_ContentLayoutItem>& pLayoutItem);
-  void AddTrailerBeforeSplit(
-      float fSplitPos,
-      const RetainPtr<CXFA_ContentLayoutItem>& pTrailerLayoutItem,
-      bool bUseInherited);
-  void AddLeaderAfterSplit(
-      const RetainPtr<CXFA_ContentLayoutItem>& pLeaderLayoutItem);
+  void UpdatePendingItemLayout(CXFA_ContentLayoutItem* pLayoutItem);
+  void AddTrailerBeforeSplit(float fSplitPos,
+                             CXFA_ContentLayoutItem* pTrailerLayoutItem,
+                             bool bUseInherited);
+  void AddLeaderAfterSplit(CXFA_ContentLayoutItem* pLeaderLayoutItem);
   void AddPendingNode(CXFA_Node* pPendingNode, bool bBreakPending);
   float InsertPendingItems(CXFA_Node* pCurChildNode);
   Result InsertFlowedItem(
@@ -171,7 +179,7 @@
       float fContainerHeight,
       XFA_AttributeValue eFlowStrategy,
       uint8_t* uCurHAlignState,
-      std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
+      std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
       bool bUseBreakControl,
       float fAvailHeight,
       float fRealHeight,
@@ -217,18 +225,19 @@
   float m_fLastRowWidth = 0;
   float m_fLastRowY = 0;
   float m_fWidthLimit = 0;
-  CXFA_Node* const m_pFormNode;
-  CXFA_Node* m_pCurChildNode = nullptr;
-  CXFA_Node* m_pKeepHeadNode = nullptr;
-  CXFA_Node* m_pKeepTailNode = nullptr;
-  RetainPtr<CXFA_ContentLayoutItem> m_pLayoutItem;
-  RetainPtr<CXFA_ContentLayoutItem> m_pOldLayoutItem;
-  UnownedPtr<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
+  UnownedPtr<cppgc::Heap> m_pHeap;
+  cppgc::Member<CXFA_Node> const m_pFormNode;
+  cppgc::Member<CXFA_Node> m_pCurChildNode;
+  cppgc::Member<CXFA_Node> m_pKeepHeadNode;
+  cppgc::Member<CXFA_Node> m_pKeepTailNode;
+  cppgc::Member<CXFA_ContentLayoutItem> m_pLayoutItem;
+  cppgc::Member<CXFA_ContentLayoutItem> m_pOldLayoutItem;
+  cppgc::Member<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
   std::vector<float> m_rgSpecifiedColumnWidths;
-  std::vector<RetainPtr<CXFA_ContentLayoutItem>> m_ArrayKeepItems;
+  std::vector<cppgc::Member<CXFA_ContentLayoutItem>> m_ArrayKeepItems;
   std::list<CXFA_Node*> m_PendingNodes;
   std::map<CXFA_Node*, int32_t> m_PendingNodesCount;
-  std::unique_ptr<CXFA_ContentLayoutProcessor> m_pCurChildPreprocessor;
+  cppgc::Member<CXFA_ContentLayoutProcessor> m_pCurChildPreprocessor;
 };
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.cpp b/xfa/fxfa/layout/cxfa_layoutitem.cpp
index b4523c9..916c693 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutitem.cpp
@@ -17,19 +17,19 @@
 #include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 
-void XFA_ReleaseLayoutItem(const RetainPtr<CXFA_LayoutItem>& pLayoutItem) {
-  RetainPtr<CXFA_LayoutItem> pNode(pLayoutItem->GetFirstChild());
+void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem) {
+  CXFA_LayoutItem* pNode = pLayoutItem->GetFirstChild();
   while (pNode) {
-    RetainPtr<CXFA_LayoutItem> pNext(pNode->GetNextSibling());
+    CXFA_LayoutItem* pNext = pNode->GetNextSibling();
     XFA_ReleaseLayoutItem(pNode);
-    pNode = std::move(pNext);
+    pNode = pNext;
   }
   CXFA_Document* pDocument = pLayoutItem->GetFormNode()->GetDocument();
   CXFA_FFNotify* pNotify = pDocument->GetNotify();
   auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
-  pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
+  pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
   if (pLayoutItem->GetFormNode()->GetElementType() == XFA_Element::PageArea) {
-    pNotify->OnPageEvent(ToViewLayoutItem(pLayoutItem.Get()),
+    pNotify->OnPageEvent(ToViewLayoutItem(pLayoutItem),
                          XFA_PAGEVIEWEVENT_PostRemoved);
   }
   pLayoutItem->RemoveSelfIfParented();
@@ -38,13 +38,20 @@
 CXFA_LayoutItem::CXFA_LayoutItem(CXFA_Node* pNode, ItemType type)
     : m_ItemType(type), m_pFormNode(pNode) {}
 
-CXFA_LayoutItem::~CXFA_LayoutItem() {
-  CHECK(!GetParent());
-  if (m_pFormNode) {
-    auto* pJSObj = m_pFormNode->JSObject();
-    if (pJSObj && pJSObj->GetLayoutItem() == this)
-      pJSObj->SetLayoutItem(nullptr);
-  }
+CXFA_LayoutItem::~CXFA_LayoutItem() = default;
+
+void CXFA_LayoutItem::PreFinalize() {
+  if (!m_pFormNode)
+    return;
+
+  auto* pJSObj = m_pFormNode->JSObject();
+  if (pJSObj && pJSObj->GetLayoutItem() == this)
+    pJSObj->SetLayoutItem(nullptr);
+}
+
+void CXFA_LayoutItem::Trace(cppgc::Visitor* visitor) const {
+  GCedTreeNode<CXFA_LayoutItem>::Trace(visitor);
+  visitor->Trace(m_pFormNode);
 }
 
 CXFA_ViewLayoutItem* CXFA_LayoutItem::AsViewLayoutItem() {
@@ -75,3 +82,8 @@
   }
   return nullptr;
 }
+
+void CXFA_LayoutItem::SetFormNode(CXFA_Node* pNode) {
+  // Not in header, assignment requires complete type, not just forward decl.
+  m_pFormNode = pNode;
+}
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.h b/xfa/fxfa/layout/cxfa_layoutitem.h
index e5662ec..d515783 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.h
+++ b/xfa/fxfa/layout/cxfa_layoutitem.h
@@ -7,19 +7,31 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
 #define XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
 
-#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/retained_tree_node.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/gced_tree_node.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/prefinalizer.h"
+#include "v8/include/cppgc/visitor.h"
 
 class CXFA_ContentLayoutItem;
 class CXFA_LayoutProcessor;
 class CXFA_Node;
 class CXFA_ViewLayoutItem;
 
-class CXFA_LayoutItem : public RetainedTreeNode<CXFA_LayoutItem> {
+class CXFA_LayoutItem : public GCedTreeNode<CXFA_LayoutItem> {
+  CPPGC_USING_PRE_FINALIZER(CXFA_LayoutItem, PreFinalize);
+
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_LayoutItem() override;
 
+  void PreFinalize();
+
+  // GCedTreeNode:
+  void Trace(cppgc::Visitor* visitor) const override;
+
   bool IsViewLayoutItem() const { return m_ItemType == kViewItem; }
   bool IsContentLayoutItem() const { return m_ItemType == kContentItem; }
   CXFA_ViewLayoutItem* AsViewLayoutItem();
@@ -29,7 +41,7 @@
 
   const CXFA_ViewLayoutItem* GetPage() const;
   CXFA_Node* GetFormNode() const { return m_pFormNode.Get(); }
-  void SetFormNode(CXFA_Node* pNode) { m_pFormNode = pNode; }
+  void SetFormNode(CXFA_Node* pNode);
 
  protected:
   enum ItemType { kViewItem, kContentItem };
@@ -37,7 +49,7 @@
 
  private:
   const ItemType m_ItemType;
-  UnownedPtr<CXFA_Node> m_pFormNode;
+  cppgc::Member<CXFA_Node> m_pFormNode;
 };
 
 inline CXFA_ViewLayoutItem* ToViewLayoutItem(CXFA_LayoutItem* item) {
@@ -48,6 +60,6 @@
   return item ? item->AsContentLayoutItem() : nullptr;
 }
 
-void XFA_ReleaseLayoutItem(const RetainPtr<CXFA_LayoutItem>& pLayoutItem);
+void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem);
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
diff --git a/xfa/fxfa/layout/cxfa_layoutprocessor.cpp b/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
index c9ea12c..cb4f7c4 100644
--- a/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
@@ -31,6 +31,14 @@
 
 CXFA_LayoutProcessor::~CXFA_LayoutProcessor() = default;
 
+void CXFA_LayoutProcessor::Trace(cppgc::Visitor* visitor) const {
+  CXFA_Document::LayoutProcessorIface::Trace(visitor);
+  visitor->Trace(m_pViewLayoutProcessor);
+  visitor->Trace(m_pContentLayoutProcessor);
+  for (const auto& container : m_rgChangedContainers)
+    visitor->Trace(container);
+}
+
 void CXFA_LayoutProcessor::SetForceRelayout(bool bForceRestart) {
   m_bNeedLayout = bForceRestart;
 }
@@ -39,7 +47,7 @@
   if (!bForceRestart && !NeedLayout())
     return 100;
 
-  m_pContentLayoutProcessor.reset();
+  m_pContentLayoutProcessor = nullptr;
   m_nProgressCounter = 0;
   CXFA_Node* pFormPacketNode =
       ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form));
@@ -51,16 +59,21 @@
   if (!pFormRoot)
     return -1;
 
-  if (!m_pViewLayoutProcessor)
-    m_pViewLayoutProcessor = std::make_unique<CXFA_ViewLayoutProcessor>(this);
+  if (!m_pViewLayoutProcessor) {
+    m_pViewLayoutProcessor =
+        cppgc::MakeGarbageCollected<CXFA_ViewLayoutProcessor>(
+            GetHeap()->GetAllocationHandle(), GetHeap(), this);
+  }
   if (!m_pViewLayoutProcessor->InitLayoutPage(pFormRoot))
     return -1;
 
   if (!m_pViewLayoutProcessor->PrepareFirstPage(pFormRoot))
     return -1;
 
-  m_pContentLayoutProcessor = std::make_unique<CXFA_ContentLayoutProcessor>(
-      pFormRoot, m_pViewLayoutProcessor.get());
+  m_pContentLayoutProcessor =
+      cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
+          GetHeap()->GetAllocationHandle(), GetHeap(), pFormRoot,
+          m_pViewLayoutProcessor);
   m_nProgressCounter = 1;
   return 0;
 }
@@ -82,7 +95,7 @@
     if (eStatus != CXFA_ContentLayoutProcessor::Result::kDone)
       m_nProgressCounter++;
 
-    RetainPtr<CXFA_ContentLayoutItem> pLayoutItem =
+    CXFA_ContentLayoutItem* pLayoutItem =
         m_pContentLayoutProcessor->ExtractLayoutItem();
     if (pLayoutItem)
       pLayoutItem->m_sPos = CFX_PointF(fPosX, fPosY);
diff --git a/xfa/fxfa/layout/cxfa_layoutprocessor.h b/xfa/fxfa/layout/cxfa_layoutprocessor.h
index 72c4b47..a37115c 100644
--- a/xfa/fxfa/layout/cxfa_layoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_layoutprocessor.h
@@ -7,11 +7,14 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_LAYOUTPROCESSOR_H_
 #define XFA_FXFA_LAYOUT_CXFA_LAYOUTPROCESSOR_H_
 
-#include <memory>
 #include <vector>
 
 #include "core/fxcrt/fx_system.h"
 #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 "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 
 class CXFA_ContentLayoutProcessor;
@@ -28,9 +31,11 @@
  public:
   static CXFA_LayoutProcessor* FromDocument(const CXFA_Document* pXFADoc);
 
-  explicit CXFA_LayoutProcessor(cppgc::Heap* pHeap);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_LayoutProcessor() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_Document::LayoutProcessorIface:
   void SetForceRelayout(bool bForceRestart) override;
   void AddChangedContainer(CXFA_Node* pContainer) override;
@@ -43,19 +48,20 @@
   CXFA_ViewLayoutItem* GetPage(int32_t index) const;
   CXFA_LayoutItem* GetLayoutItem(CXFA_Node* pFormItem);
   CXFA_ContentLayoutProcessor* GetRootContentLayoutProcessor() const {
-    return m_pContentLayoutProcessor.get();
+    return m_pContentLayoutProcessor;
   }
   CXFA_ViewLayoutProcessor* GetLayoutPageMgr() const {
-    return m_pViewLayoutProcessor.get();
+    return m_pViewLayoutProcessor;
   }
 
  private:
+  explicit CXFA_LayoutProcessor(cppgc::Heap* pHeap);
   bool NeedLayout() const;
 
   UnownedPtr<cppgc::Heap> const m_pHeap;
-  std::unique_ptr<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
-  std::unique_ptr<CXFA_ContentLayoutProcessor> m_pContentLayoutProcessor;
-  std::vector<CXFA_Node*> m_rgChangedContainers;
+  cppgc::Member<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
+  cppgc::Member<CXFA_ContentLayoutProcessor> m_pContentLayoutProcessor;
+  std::vector<cppgc::Member<CXFA_Node>> m_rgChangedContainers;
   uint32_t m_nProgressCounter = 0;
   bool m_bNeedLayout = true;
 };
diff --git a/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h b/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
index f71d708..92e58e5 100644
--- a/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
+++ b/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
@@ -7,7 +7,6 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
 #define XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
 
-#include "core/fxcrt/retain_ptr.h"
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
 #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
 
@@ -27,6 +26,6 @@
 using CXFA_LayoutItemIterator =
     CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
                               CXFA_TraverseStrategy_LayoutItem,
-                              RetainPtr<CXFA_LayoutItem>>;
+                              CXFA_LayoutItem*>;
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutitem.cpp b/xfa/fxfa/layout/cxfa_viewlayoutitem.cpp
index fcef2ab..9d76f7c 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutitem.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutitem.cpp
@@ -16,17 +16,19 @@
 #include "xfa/fxfa/parser/cxfa_medium.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 
-CXFA_ViewLayoutItem::CXFA_ViewLayoutItem(
-    CXFA_Node* pNode,
-    std::unique_ptr<CXFA_FFPageView> pPageView)
-    : CXFA_LayoutItem(pNode, kViewItem), m_pFFPageView(std::move(pPageView)) {
+CXFA_ViewLayoutItem::CXFA_ViewLayoutItem(CXFA_Node* pNode,
+                                         CXFA_FFPageView* pPageView)
+    : CXFA_LayoutItem(pNode, kViewItem), m_pFFPageView(pPageView) {
   if (m_pFFPageView)
     m_pFFPageView->SetLayoutItem(this);
 }
 
-CXFA_ViewLayoutItem::~CXFA_ViewLayoutItem() {
-  if (m_pFFPageView)
-    m_pFFPageView->SetLayoutItem(nullptr);
+CXFA_ViewLayoutItem::~CXFA_ViewLayoutItem() = default;
+
+void CXFA_ViewLayoutItem::Trace(cppgc::Visitor* visitor) const {
+  CXFA_LayoutItem::Trace(visitor);
+  visitor->Trace(m_pOldSubform);
+  visitor->Trace(m_pFFPageView);
 }
 
 CXFA_LayoutProcessor* CXFA_ViewLayoutItem::GetLayout() const {
@@ -59,3 +61,7 @@
 CXFA_Node* CXFA_ViewLayoutItem::GetMasterPage() const {
   return GetFormNode();
 }
+
+void CXFA_ViewLayoutItem::SetOldSubform(CXFA_Node* pSubform) {
+  m_pOldSubform = pSubform;
+}
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutitem.h b/xfa/fxfa/layout/cxfa_viewlayoutitem.h
index f25366c..cf93279 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutitem.h
+++ b/xfa/fxfa/layout/cxfa_viewlayoutitem.h
@@ -7,32 +7,33 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTITEM_H_
 #define XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTITEM_H_
 
-#include <memory>
-
 #include "core/fxcrt/fx_coordinates.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
 
 class CXFA_FFPageView;
 
 class CXFA_ViewLayoutItem final : public CXFA_LayoutItem {
  public:
-  CONSTRUCT_VIA_MAKE_RETAIN;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ViewLayoutItem() override;
 
-  CXFA_FFPageView* GetPageView() const { return m_pFFPageView.get(); }
+  void Trace(cppgc::Visitor* visitor) const override;
+
+  CXFA_FFPageView* GetPageView() const { return m_pFFPageView; }
   CXFA_LayoutProcessor* GetLayout() const;
   int32_t GetPageIndex() const;
   CFX_SizeF GetPageSize() const;
   CXFA_Node* GetMasterPage() const;
-  CXFA_Node* GetOldSubform() const { return m_pOldSubform.Get(); }
-  void SetOldSubform(CXFA_Node* pSubform) { m_pOldSubform = pSubform; }
+  CXFA_Node* GetOldSubform() const { return m_pOldSubform; }
+  void SetOldSubform(CXFA_Node* pSubform);
 
  private:
-  CXFA_ViewLayoutItem(CXFA_Node* pNode,
-                      std::unique_ptr<CXFA_FFPageView> pPageView);
+  CXFA_ViewLayoutItem(CXFA_Node* pNode, CXFA_FFPageView* pPageView);
 
-  std::unique_ptr<CXFA_FFPageView> const m_pFFPageView;
-  UnownedPtr<CXFA_Node> m_pOldSubform;
+  cppgc::Member<CXFA_FFPageView> const m_pFFPageView;
+  cppgc::Member<CXFA_Node> m_pOldSubform;
 };
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTITEM_H_
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index 3c52198..ae3ef5a 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -157,7 +157,7 @@
   }
 }
 
-void ReorderLayoutItemToTail(const RetainPtr<CXFA_LayoutItem>& pLayoutItem) {
+void ReorderLayoutItemToTail(CXFA_LayoutItem* pLayoutItem) {
   CXFA_LayoutItem* pParentLayoutItem = pLayoutItem->GetParent();
   if (!pParentLayoutItem)
     return;
@@ -245,12 +245,11 @@
 void SyncRemoveLayoutItem(CXFA_LayoutItem* pLayoutItem,
                           CXFA_FFNotify* pNotify,
                           CXFA_LayoutProcessor* pDocLayout) {
-  RetainPtr<CXFA_LayoutItem> pCurLayoutItem(pLayoutItem->GetFirstChild());
+  CXFA_LayoutItem* pCurLayoutItem = pLayoutItem->GetFirstChild();
   while (pCurLayoutItem) {
-    RetainPtr<CXFA_LayoutItem> pNextLayoutItem(
-        pCurLayoutItem->GetNextSibling());
-    SyncRemoveLayoutItem(pCurLayoutItem.Get(), pNotify, pDocLayout);
-    pCurLayoutItem = std::move(pNextLayoutItem);
+    CXFA_LayoutItem* pNextLayoutItem = pCurLayoutItem->GetNextSibling();
+    SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+    pCurLayoutItem = pNextLayoutItem;
   }
   pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
   pLayoutItem->RemoveSelfIfParented();
@@ -332,21 +331,48 @@
 
 CXFA_ViewLayoutProcessor::CXFA_ViewRecord::~CXFA_ViewRecord() = default;
 
+void CXFA_ViewLayoutProcessor::CXFA_ViewRecord::Trace(
+    cppgc::Visitor* visitor) const {
+  visitor->Trace(pCurPageSet);
+  visitor->Trace(pCurPageArea);
+  visitor->Trace(pCurContentArea);
+}
+
 CXFA_ViewLayoutProcessor::CXFA_ViewLayoutProcessor(
+    cppgc::Heap* pHeap,
     CXFA_LayoutProcessor* pLayoutProcessor)
-    : m_pLayoutProcessor(pLayoutProcessor),
+    : m_pHeap(pHeap),
+      m_pLayoutProcessor(pLayoutProcessor),
       m_CurrentViewRecordIter(m_ProposedViewRecords.end()) {}
 
-CXFA_ViewLayoutProcessor::~CXFA_ViewLayoutProcessor() {
+CXFA_ViewLayoutProcessor::~CXFA_ViewLayoutProcessor() = default;
+
+void CXFA_ViewLayoutProcessor::PreFinalize() {
   ClearData();
-  RetainPtr<CXFA_LayoutItem> pLayoutItem(GetRootLayoutItem());
+  CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem();
   while (pLayoutItem) {
     CXFA_LayoutItem* pNextLayout = pLayoutItem->GetNextSibling();
     XFA_ReleaseLayoutItem(pLayoutItem);
-    pLayoutItem.Reset(pNextLayout);
+    pLayoutItem = pNextLayout;
   }
 }
 
+void CXFA_ViewLayoutProcessor::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pLayoutProcessor);
+  visitor->Trace(m_pPageSetNode);
+  visitor->Trace(m_pCurPageArea);
+  visitor->Trace(m_pPageSetRootLayoutItem);
+  visitor->Trace(m_pPageSetCurLayoutItem);
+  for (const auto& record : m_ProposedViewRecords)
+    visitor->Trace(*record);
+
+  if (m_CurrentViewRecordIter != m_ProposedViewRecords.end())
+    visitor->Trace(*m_CurrentViewRecordIter);
+
+  for (const auto& page : m_PageArray)
+    visitor->Trace(page);
+}
+
 bool CXFA_ViewLayoutProcessor::InitLayoutPage(CXFA_Node* pFormNode) {
   PrepareLayout();
   CXFA_Node* pTemplateNode = pFormNode->GetTemplateNodeIfExists();
@@ -360,8 +386,8 @@
   if (m_pPageSetRootLayoutItem) {
     m_pPageSetRootLayoutItem->RemoveSelfIfParented();
   } else {
-    m_pPageSetRootLayoutItem =
-        pdfium::MakeRetain<CXFA_ViewLayoutItem>(m_pPageSetNode, nullptr);
+    m_pPageSetRootLayoutItem = cppgc::MakeGarbageCollected<CXFA_ViewLayoutItem>(
+        GetHeap()->GetAllocationHandle(), m_pPageSetNode, nullptr);
   }
   m_pPageSetCurLayoutItem = m_pPageSetRootLayoutItem;
   m_pPageSetNode->JSObject()->SetLayoutItem(m_pPageSetRootLayoutItem.Get());
@@ -526,7 +552,7 @@
 }
 
 void CXFA_ViewLayoutProcessor::SubmitContentItem(
-    const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem,
+    CXFA_ContentLayoutItem* pContentLayoutItem,
     CXFA_ContentLayoutProcessor::Result eStatus) {
   if (pContentLayoutItem) {
     if (!HasCurrentViewRecord())
@@ -551,8 +577,7 @@
   if (!HasCurrentViewRecord())
     return 0.0f;
 
-  RetainPtr<CXFA_ViewLayoutItem> pLayoutItem =
-      GetCurrentViewRecord()->pCurContentArea;
+  CXFA_ViewLayoutItem* pLayoutItem = GetCurrentViewRecord()->pCurContentArea;
   if (!pLayoutItem || !pLayoutItem->GetFormNode())
     return 0.0f;
 
@@ -565,35 +590,36 @@
   return FLT_MAX;
 }
 
-CXFA_ViewLayoutProcessor::CXFA_ViewRecord*
-CXFA_ViewLayoutProcessor::AppendNewRecord(
-    std::unique_ptr<CXFA_ViewRecord> pNewRecord) {
-  m_ProposedViewRecords.push_back(std::move(pNewRecord));
-  return m_ProposedViewRecords.back().get();
+void CXFA_ViewLayoutProcessor::AppendNewRecord(CXFA_ViewRecord* pNewRecord) {
+  m_ProposedViewRecords.emplace_back(pNewRecord);
 }
 
 CXFA_ViewLayoutProcessor::CXFA_ViewRecord*
 CXFA_ViewLayoutProcessor::CreateViewRecord(CXFA_Node* pPageNode,
                                            bool bCreateNew) {
   ASSERT(pPageNode);
-  auto pNewRecord = std::make_unique<CXFA_ViewRecord>();
+  auto* pNewRecord = cppgc::MakeGarbageCollected<CXFA_ViewRecord>(
+      GetHeap()->GetAllocationHandle());
   if (!HasCurrentViewRecord()) {
     CXFA_Node* pPageSet = pPageNode->GetParent();
     if (pPageSet == m_pPageSetNode) {
       pNewRecord->pCurPageSet = m_pPageSetRootLayoutItem;
     } else {
-      auto pPageSetLayoutItem =
-          pdfium::MakeRetain<CXFA_ViewLayoutItem>(pPageSet, nullptr);
-      pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem.Get());
+      auto* pPageSetLayoutItem =
+          cppgc::MakeGarbageCollected<CXFA_ViewLayoutItem>(
+              GetHeap()->GetAllocationHandle(), pPageSet, nullptr);
+      pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem);
       m_pPageSetRootLayoutItem->AppendLastChild(pPageSetLayoutItem);
-      pNewRecord->pCurPageSet = std::move(pPageSetLayoutItem);
+      pNewRecord->pCurPageSet = pPageSetLayoutItem;
     }
-    return AppendNewRecord(std::move(pNewRecord));
+    AppendNewRecord(pNewRecord);
+    return pNewRecord;
   }
 
   if (!IsPageSetRootOrderedOccurrence()) {
     *pNewRecord = *GetCurrentViewRecord();
-    return AppendNewRecord(std::move(pNewRecord));
+    AppendNewRecord(pNewRecord);
+    return pNewRecord;
   }
 
   CXFA_Node* pPageSet = pPageNode->GetParent();
@@ -601,14 +627,14 @@
     if (pPageSet == m_pPageSetNode) {
       pNewRecord->pCurPageSet = m_pPageSetCurLayoutItem;
     } else {
-      RetainPtr<CXFA_ViewLayoutItem> pParentLayoutItem(
-          ToViewLayoutItem(pPageSet->JSObject()->GetLayoutItem()));
+      CXFA_ViewLayoutItem* pParentLayoutItem =
+          ToViewLayoutItem(pPageSet->JSObject()->GetLayoutItem());
       if (!pParentLayoutItem)
         pParentLayoutItem = m_pPageSetCurLayoutItem;
-
       pNewRecord->pCurPageSet = pParentLayoutItem;
     }
-    return AppendNewRecord(std::move(pNewRecord));
+    AppendNewRecord(pNewRecord);
+    return pNewRecord;
   }
 
   CXFA_ViewLayoutItem* pParentPageSetLayout = nullptr;
@@ -619,52 +645,55 @@
     pParentPageSetLayout =
         ToViewLayoutItem(pPageSet->GetParent()->JSObject()->GetLayoutItem());
   }
-  auto pPageSetLayoutItem =
-      pdfium::MakeRetain<CXFA_ViewLayoutItem>(pPageSet, nullptr);
-  pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem.Get());
+  auto* pPageSetLayoutItem = cppgc::MakeGarbageCollected<CXFA_ViewLayoutItem>(
+      GetHeap()->GetAllocationHandle(), pPageSet, nullptr);
+  pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem);
   if (!pParentPageSetLayout) {
-    RetainPtr<CXFA_ViewLayoutItem> pPrePageSet(m_pPageSetRootLayoutItem);
-    while (pPrePageSet->GetNextSibling()) {
-      pPrePageSet.Reset(pPrePageSet->GetNextSibling()->AsViewLayoutItem());
-    }
+    CXFA_ViewLayoutItem* pPrePageSet = m_pPageSetRootLayoutItem;
+    while (pPrePageSet->GetNextSibling())
+      pPrePageSet = pPrePageSet->GetNextSibling()->AsViewLayoutItem();
+
     if (pPrePageSet->GetParent()) {
-      pPrePageSet->GetParent()->InsertAfter(pPageSetLayoutItem,
-                                            pPrePageSet.Get());
+      pPrePageSet->GetParent()->InsertAfter(pPageSetLayoutItem, pPrePageSet);
     }
     m_pPageSetCurLayoutItem = pPageSetLayoutItem;
   } else {
     pParentPageSetLayout->AppendLastChild(pPageSetLayoutItem);
   }
   pNewRecord->pCurPageSet = pPageSetLayoutItem;
-  return AppendNewRecord(std::move(pNewRecord));
+  AppendNewRecord(pNewRecord);
+  return pNewRecord;
 }
 
 CXFA_ViewLayoutProcessor::CXFA_ViewRecord*
 CXFA_ViewLayoutProcessor::CreateViewRecordSimple() {
-  auto pNewRecord = std::make_unique<CXFA_ViewRecord>();
+  auto* pNewRecord = cppgc::MakeGarbageCollected<CXFA_ViewRecord>(
+      GetHeap()->GetAllocationHandle());
   if (HasCurrentViewRecord())
     *pNewRecord = *GetCurrentViewRecord();
   else
     pNewRecord->pCurPageSet = m_pPageSetRootLayoutItem;
-  return AppendNewRecord(std::move(pNewRecord));
+  AppendNewRecord(pNewRecord);
+  return pNewRecord;
 }
 
 void CXFA_ViewLayoutProcessor::AddPageAreaLayoutItem(
     CXFA_ViewRecord* pNewRecord,
     CXFA_Node* pNewPageArea) {
-  RetainPtr<CXFA_ViewLayoutItem> pNewPageAreaLayoutItem;
+  CXFA_ViewLayoutItem* pNewPageAreaLayoutItem = nullptr;
   if (pdfium::IndexInBounds(m_PageArray, m_nAvailPages)) {
-    RetainPtr<CXFA_ViewLayoutItem> pViewItem = m_PageArray[m_nAvailPages];
+    CXFA_ViewLayoutItem* pViewItem = m_PageArray[m_nAvailPages];
     pViewItem->SetFormNode(pNewPageArea);
     m_nAvailPages++;
-    pNewPageAreaLayoutItem = std::move(pViewItem);
+    pNewPageAreaLayoutItem = pViewItem;
   } else {
     CXFA_FFNotify* pNotify = pNewPageArea->GetDocument()->GetNotify();
-    auto pViewItem = pdfium::MakeRetain<CXFA_ViewLayoutItem>(
-        pNewPageArea, pNotify->OnCreateViewLayoutItem(pNewPageArea));
+    auto* pViewItem = cppgc::MakeGarbageCollected<CXFA_ViewLayoutItem>(
+        GetHeap()->GetAllocationHandle(), pNewPageArea,
+        pNotify->OnCreateViewLayoutItem(pNewPageArea));
     m_PageArray.push_back(pViewItem);
     m_nAvailPages++;
-    pNotify->OnPageEvent(pViewItem.Get(), XFA_PAGEVIEWEVENT_PostRemoved);
+    pNotify->OnPageEvent(pViewItem, XFA_PAGEVIEWEVENT_PostRemoved);
     pNewPageAreaLayoutItem = pViewItem;
   }
   pNewRecord->pCurPageSet->AppendLastChild(pNewPageAreaLayoutItem);
@@ -679,10 +708,10 @@
     pNewRecord->pCurContentArea = nullptr;
     return;
   }
-  auto pNewViewLayoutItem =
-      pdfium::MakeRetain<CXFA_ViewLayoutItem>(pContentArea, nullptr);
+  auto* pNewViewLayoutItem = cppgc::MakeGarbageCollected<CXFA_ViewLayoutItem>(
+      GetHeap()->GetAllocationHandle(), pContentArea, nullptr);
   pNewRecord->pCurPageArea->AppendLastChild(pNewViewLayoutItem);
-  pNewRecord->pCurContentArea = std::move(pNewViewLayoutItem);
+  pNewRecord->pCurContentArea = pNewViewLayoutItem;
 }
 
 void CXFA_ViewLayoutProcessor::FinishPaginatedPageSets() {
@@ -1389,7 +1418,7 @@
         return false;
 
       CXFA_ViewRecord* pNewRecord = CreateViewRecordSimple();
-      pNewRecord->pCurContentArea.Reset(pContentAreaLayout.value());
+      pNewRecord->pCurContentArea = pContentAreaLayout.value();
       return true;
     }
   }
@@ -1546,11 +1575,11 @@
           GetNextAvailPageArea(nullptr, nullptr, false, true);
       m_pCurPageArea = pSrcPage;
       m_nCurPageCount = nSrcPageCount;
-      CXFA_ViewRecord* pPrevRecord = psSrcIter->get();
+      CXFA_ViewRecord* pPrevRecord = psSrcIter->Get();
       ++psSrcIter;
       while (psSrcIter != m_ProposedViewRecords.end()) {
         auto psSaveIter = psSrcIter++;
-        RemoveLayoutRecord(psSaveIter->get(), pPrevRecord);
+        RemoveLayoutRecord(psSaveIter->Get(), pPrevRecord);
         m_ProposedViewRecords.erase(psSaveIter);
       }
       if (pNextPage) {
@@ -1596,21 +1625,20 @@
   CXFA_Document* pDocument = m_pPageSetNode->GetDocument();
   CXFA_FFNotify* pNotify = pDocument->GetNotify();
   auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
-  RetainPtr<CXFA_LayoutItem> pCurLayoutItem(pParentLayoutItem->GetFirstChild());
+  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->GetFirstChild();
   while (pCurLayoutItem) {
-    RetainPtr<CXFA_LayoutItem> pNextLayoutItem(
-        pCurLayoutItem->GetNextSibling());
+    CXFA_LayoutItem* pNextLayoutItem = pCurLayoutItem->GetNextSibling();
     if (pCurLayoutItem->IsContentLayoutItem()) {
       if (pCurLayoutItem->GetFormNode()->HasRemovedChildren()) {
-        SyncRemoveLayoutItem(pCurLayoutItem.Get(), pNotify, pDocLayout);
-        pCurLayoutItem = std::move(pNextLayoutItem);
+        SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+        pCurLayoutItem = pNextLayoutItem;
         continue;
       }
       if (pCurLayoutItem->GetFormNode()->IsLayoutGeneratedNode())
         pCurLayoutItem->GetFormNode()->SetNodeAndDescendantsUnused();
     }
-    SaveLayoutItemChildren(pCurLayoutItem.Get());
-    pCurLayoutItem = std::move(pNextLayoutItem);
+    SaveLayoutItemChildren(pCurLayoutItem);
+    pCurLayoutItem = pNextLayoutItem;
   }
 }
 
@@ -1719,11 +1747,10 @@
               for (CXFA_Node* pIter = sIterator.GetCurrent(); pIter;
                    pIter = sIterator.MoveToNext()) {
                 if (pIter->GetElementType() != XFA_Element::ContentArea) {
-                  RetainPtr<CXFA_LayoutItem> pLayoutItem(
-                      pIter->JSObject()->GetLayoutItem());
+                  CXFA_LayoutItem* pLayoutItem =
+                      pIter->JSObject()->GetLayoutItem();
                   if (pLayoutItem) {
-                    pNotify->OnLayoutItemRemoving(pDocLayout,
-                                                  pLayoutItem.Get());
+                    pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
                     pLayoutItem->RemoveSelfIfParented();
                   }
                 }
@@ -1790,18 +1817,17 @@
             CXFA_ContainerIterator iteChild(pNode);
             CXFA_Node* pChildNode = iteChild.MoveToNext();
             for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
-              RetainPtr<CXFA_LayoutItem> pLayoutItem(
-                  pChildNode->JSObject()->GetLayoutItem());
+              CXFA_LayoutItem* pLayoutItem =
+                  pChildNode->JSObject()->GetLayoutItem();
               if (pLayoutItem) {
-                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
+                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
                 pLayoutItem->RemoveSelfIfParented();
               }
             }
           } else if (eType != XFA_Element::ContentArea) {
-            RetainPtr<CXFA_LayoutItem> pLayoutItem(
-                pNode->JSObject()->GetLayoutItem());
+            CXFA_LayoutItem* pLayoutItem = pNode->JSObject()->GetLayoutItem();
             if (pLayoutItem) {
-              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
+              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
               pLayoutItem->RemoveSelfIfParented();
             }
           }
@@ -1884,9 +1910,9 @@
 
   int32_t nPage = pdfium::CollectionSize<int32_t>(m_PageArray);
   for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) {
-    RetainPtr<CXFA_ViewLayoutItem> pPage = m_PageArray[i];
+    CXFA_ViewLayoutItem* pPage = m_PageArray[i];
     m_PageArray.erase(m_PageArray.begin() + i);
-    pNotify->OnPageEvent(pPage.Get(), XFA_PAGEVIEWEVENT_PostRemoved);
+    pNotify->OnPageEvent(pPage, XFA_PAGEVIEWEVENT_PostRemoved);
   }
   ClearData();
 }
@@ -1899,7 +1925,7 @@
   if (!m_pPageSetRootLayoutItem)
     return;
 
-  RetainPtr<CXFA_ViewLayoutItem> pRootLayoutItem = m_pPageSetRootLayoutItem;
+  CXFA_ViewLayoutItem* pRootLayoutItem = m_pPageSetRootLayoutItem;
   if (pRootLayoutItem &&
       pRootLayoutItem->GetFormNode()->GetPacketType() == XFA_PacketType::Form) {
     CXFA_Node* pPageSetFormNode = pRootLayoutItem->GetFormNode();
@@ -1925,9 +1951,9 @@
   }
   pRootLayoutItem = m_pPageSetRootLayoutItem;
   CXFA_ViewLayoutItem* pNextLayout = nullptr;
-  for (; pRootLayoutItem; pRootLayoutItem.Reset(pNextLayout)) {
+  for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
     pNextLayout = ToViewLayoutItem(pRootLayoutItem->GetNextSibling());
-    SaveLayoutItemChildren(pRootLayoutItem.Get());
+    SaveLayoutItemChildren(pRootLayoutItem);
     pRootLayoutItem->RemoveSelfIfParented();
   }
   m_pPageSetRootLayoutItem = nullptr;
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
index e623285..a0606db 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
@@ -13,14 +13,21 @@
 #include <memory>
 #include <vector>
 
-#include "core/fxcrt/retain_ptr.h"
+#include "fxjs/gc/heap.h"
 #include "third_party/base/optional.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/prefinalizer.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h"
 
 class CXFA_LayoutItem;
 class CXFA_Node;
 
-class CXFA_ViewLayoutProcessor {
+class CXFA_ViewLayoutProcessor
+    : public cppgc::GarbageCollected<CXFA_ViewLayoutProcessor> {
+  CPPGC_USING_PRE_FINALIZER(CXFA_ViewLayoutProcessor, PreFinalize);
+
  public:
   struct BreakData {
     CXFA_Node* pLeader;
@@ -33,16 +40,19 @@
     CXFA_Node* pTrailer;
   };
 
-  explicit CXFA_ViewLayoutProcessor(CXFA_LayoutProcessor* pLayoutProcessor);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ViewLayoutProcessor();
 
+  void PreFinalize();
+  void Trace(cppgc::Visitor* visitor) const;
+  cppgc::Heap* GetHeap() const { return m_pHeap.Get(); }
+
   bool InitLayoutPage(CXFA_Node* pFormNode);
   bool PrepareFirstPage(CXFA_Node* pRootSubform);
   float GetAvailHeight();
   bool GetNextAvailContentHeight(float fChildHeight);
-  void SubmitContentItem(
-      const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem,
-      CXFA_ContentLayoutProcessor::Result eStatus);
+  void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
+                         CXFA_ContentLayoutProcessor::Result eStatus);
   void FinishPaginatedPageSets();
   void SyncLayoutData();
   int32_t GetPageCount() const;
@@ -60,16 +70,23 @@
   CXFA_Node* ProcessBookendTrailer(const CXFA_Node* pBookendNode);
 
  private:
-  struct CXFA_ViewRecord {
-    CXFA_ViewRecord();
+  class CXFA_ViewRecord : public cppgc::GarbageCollected<CXFA_ViewRecord> {
+   public:
+    CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
     ~CXFA_ViewRecord();
 
-    RetainPtr<CXFA_ViewLayoutItem> pCurPageSet;
-    RetainPtr<CXFA_ViewLayoutItem> pCurPageArea;
-    RetainPtr<CXFA_ViewLayoutItem> pCurContentArea;
+    void Trace(cppgc::Visitor* visitor) const;
+
+    cppgc::Member<CXFA_ViewLayoutItem> pCurPageSet;
+    cppgc::Member<CXFA_ViewLayoutItem> pCurPageArea;
+    cppgc::Member<CXFA_ViewLayoutItem> pCurContentArea;
+
+   private:
+    CXFA_ViewRecord();
   };
 
-  using RecordList = std::list<std::unique_ptr<CXFA_ViewRecord>>;
+  CXFA_ViewLayoutProcessor(cppgc::Heap* pHeap,
+                           CXFA_LayoutProcessor* pLayoutProcessor);
 
   bool AppendNewPage(bool bFirstTemPage);
   void ReorderPendingLayoutRecordToTail(CXFA_ViewRecord* pNewRecord,
@@ -80,19 +97,19 @@
     return m_CurrentViewRecordIter != m_ProposedViewRecords.end();
   }
   CXFA_ViewRecord* GetCurrentViewRecord() {
-    return m_CurrentViewRecordIter->get();
+    return m_CurrentViewRecordIter->Get();
   }
   const CXFA_ViewRecord* GetCurrentViewRecord() const {
-    return m_CurrentViewRecordIter->get();
+    return m_CurrentViewRecordIter->Get();
   }
   void ResetToFirstViewRecord() {
     m_CurrentViewRecordIter = m_ProposedViewRecords.begin();
   }
-  RecordList::iterator GetTailPosition() {
+  std::list<cppgc::Member<CXFA_ViewRecord>>::iterator GetTailPosition() {
     auto iter = m_ProposedViewRecords.end();
     return !m_ProposedViewRecords.empty() ? std::prev(iter) : iter;
   }
-  CXFA_ViewRecord* AppendNewRecord(std::unique_ptr<CXFA_ViewRecord> pNewRecord);
+  void AppendNewRecord(CXFA_ViewRecord* pNewRecord);
   CXFA_ViewRecord* CreateViewRecord(CXFA_Node* pPageNode, bool bCreateNew);
   CXFA_ViewRecord* CreateViewRecordSimple();
   void AddPageAreaLayoutItem(CXFA_ViewRecord* pNewRecord,
@@ -160,19 +177,20 @@
   void ProcessSimplexOrDuplexPageSets(CXFA_ViewLayoutItem* pPageSetLayoutItem,
                                       bool bIsSimplex);
 
-  CXFA_LayoutProcessor* m_pLayoutProcessor = nullptr;
-  CXFA_Node* m_pPageSetNode = nullptr;
-  RetainPtr<CXFA_ViewLayoutItem> m_pPageSetRootLayoutItem;
-  RetainPtr<CXFA_ViewLayoutItem> m_pPageSetCurLayoutItem;
-  RecordList m_ProposedViewRecords;
-  RecordList::iterator m_CurrentViewRecordIter;
-  CXFA_Node* m_pCurPageArea = nullptr;
+  UnownedPtr<cppgc::Heap> m_pHeap;
+  cppgc::Member<CXFA_LayoutProcessor> m_pLayoutProcessor;
+  cppgc::Member<CXFA_Node> m_pPageSetNode;
+  cppgc::Member<CXFA_Node> m_pCurPageArea;
+  cppgc::Member<CXFA_ViewLayoutItem> m_pPageSetRootLayoutItem;
+  cppgc::Member<CXFA_ViewLayoutItem> m_pPageSetCurLayoutItem;
+  std::list<cppgc::Member<CXFA_ViewRecord>> m_ProposedViewRecords;
+  std::list<cppgc::Member<CXFA_ViewRecord>>::iterator m_CurrentViewRecordIter;
   int32_t m_nAvailPages = 0;
   int32_t m_nCurPageCount = 0;
   XFA_AttributeValue m_ePageSetMode = XFA_AttributeValue::OrderedOccurrence;
   bool m_bCreateOverFlowPage = false;
   std::map<CXFA_Node*, int32_t> m_pPageSetMap;
-  std::vector<RetainPtr<CXFA_ViewLayoutItem>> m_PageArray;
+  std::vector<cppgc::Member<CXFA_ViewLayoutItem>> m_PageArray;
 };
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_
diff --git a/xfa/fxfa/parser/BUILD.gn b/xfa/fxfa/parser/BUILD.gn
index 4d35b3a..af4cf66 100644
--- a/xfa/fxfa/parser/BUILD.gn
+++ b/xfa/fxfa/parser/BUILD.gn
@@ -684,6 +684,7 @@
     "../../fde",
     "../../fgas",
     "../../fxgraphics",
+    "//v8:cppgc",
   ]
   allow_circular_includes_from = [ "../../../fxjs" ]
   configs += [
@@ -707,6 +708,7 @@
   deps = [
     ":parser",
     "../../../fxjs",
+    "//v8:cppgc",
   ]
   pdfium_root_dir = "../../../"
 }
diff --git a/xfa/fxfa/parser/cxfa_accessiblecontent.h b/xfa/fxfa/parser/cxfa_accessiblecontent.h
index 2aea151..5339ceb 100644
--- a/xfa/fxfa/parser/cxfa_accessiblecontent.h
+++ b/xfa/fxfa/parser/cxfa_accessiblecontent.h
@@ -11,8 +11,11 @@
 
 class CXFA_AccessibleContent final : public CXFA_Node {
  public:
-  CXFA_AccessibleContent(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AccessibleContent() override;
+
+ private:
+  CXFA_AccessibleContent(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ACCESSIBLECONTENT_H_
diff --git a/xfa/fxfa/parser/cxfa_acrobat.h b/xfa/fxfa/parser/cxfa_acrobat.h
index 5711178..9f3be8a 100644
--- a/xfa/fxfa/parser/cxfa_acrobat.h
+++ b/xfa/fxfa/parser/cxfa_acrobat.h
@@ -11,8 +11,11 @@
 
 class CXFA_Acrobat final : public CXFA_Node {
  public:
-  CXFA_Acrobat(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Acrobat() override;
+
+ private:
+  CXFA_Acrobat(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ACROBAT_H_
diff --git a/xfa/fxfa/parser/cxfa_acrobat7.h b/xfa/fxfa/parser/cxfa_acrobat7.h
index 8f64044..491b6f4 100644
--- a/xfa/fxfa/parser/cxfa_acrobat7.h
+++ b/xfa/fxfa/parser/cxfa_acrobat7.h
@@ -11,8 +11,11 @@
 
 class CXFA_Acrobat7 final : public CXFA_Node {
  public:
-  CXFA_Acrobat7(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Acrobat7() override;
+
+ private:
+  CXFA_Acrobat7(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ACROBAT7_H_
diff --git a/xfa/fxfa/parser/cxfa_adbe_jsconsole.h b/xfa/fxfa/parser/cxfa_adbe_jsconsole.h
index 2fef074..1692f0d 100644
--- a/xfa/fxfa/parser/cxfa_adbe_jsconsole.h
+++ b/xfa/fxfa/parser/cxfa_adbe_jsconsole.h
@@ -11,8 +11,11 @@
 
 class CXFA_ADBE_JSConsole final : public CXFA_Node {
  public:
-  CXFA_ADBE_JSConsole(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ADBE_JSConsole() override;
+
+ private:
+  CXFA_ADBE_JSConsole(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADBE_JSCONSOLE_H_
diff --git a/xfa/fxfa/parser/cxfa_adbe_jsdebugger.h b/xfa/fxfa/parser/cxfa_adbe_jsdebugger.h
index 34fcb0c..9543977 100644
--- a/xfa/fxfa/parser/cxfa_adbe_jsdebugger.h
+++ b/xfa/fxfa/parser/cxfa_adbe_jsdebugger.h
@@ -11,8 +11,11 @@
 
 class CXFA_ADBE_JSDebugger final : public CXFA_Node {
  public:
-  CXFA_ADBE_JSDebugger(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ADBE_JSDebugger() override;
+
+ private:
+  CXFA_ADBE_JSDebugger(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADBE_JSDEBUGGER_H_
diff --git a/xfa/fxfa/parser/cxfa_addsilentprint.h b/xfa/fxfa/parser/cxfa_addsilentprint.h
index abfff47..bb157a6 100644
--- a/xfa/fxfa/parser/cxfa_addsilentprint.h
+++ b/xfa/fxfa/parser/cxfa_addsilentprint.h
@@ -11,8 +11,11 @@
 
 class CXFA_AddSilentPrint final : public CXFA_Node {
  public:
-  CXFA_AddSilentPrint(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AddSilentPrint() override;
+
+ private:
+  CXFA_AddSilentPrint(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADDSILENTPRINT_H_
diff --git a/xfa/fxfa/parser/cxfa_addviewerpreferences.h b/xfa/fxfa/parser/cxfa_addviewerpreferences.h
index 62fd6e3..46fa7d2 100644
--- a/xfa/fxfa/parser/cxfa_addviewerpreferences.h
+++ b/xfa/fxfa/parser/cxfa_addviewerpreferences.h
@@ -11,8 +11,11 @@
 
 class CXFA_AddViewerPreferences final : public CXFA_Node {
  public:
-  CXFA_AddViewerPreferences(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AddViewerPreferences() override;
+
+ private:
+  CXFA_AddViewerPreferences(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADDVIEWERPREFERENCES_H_
diff --git a/xfa/fxfa/parser/cxfa_adjustdata.h b/xfa/fxfa/parser/cxfa_adjustdata.h
index 463f2e6..c3cf1d8 100644
--- a/xfa/fxfa/parser/cxfa_adjustdata.h
+++ b/xfa/fxfa/parser/cxfa_adjustdata.h
@@ -11,8 +11,11 @@
 
 class CXFA_AdjustData final : public CXFA_Node {
  public:
-  CXFA_AdjustData(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AdjustData() override;
+
+ private:
+  CXFA_AdjustData(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADJUSTDATA_H_
diff --git a/xfa/fxfa/parser/cxfa_adobeextensionlevel.h b/xfa/fxfa/parser/cxfa_adobeextensionlevel.h
index 5e0a507..cb90238 100644
--- a/xfa/fxfa/parser/cxfa_adobeextensionlevel.h
+++ b/xfa/fxfa/parser/cxfa_adobeextensionlevel.h
@@ -11,8 +11,11 @@
 
 class CXFA_AdobeExtensionLevel final : public CXFA_Node {
  public:
-  CXFA_AdobeExtensionLevel(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AdobeExtensionLevel() override;
+
+ private:
+  CXFA_AdobeExtensionLevel(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ADOBEEXTENSIONLEVEL_H_
diff --git a/xfa/fxfa/parser/cxfa_agent.h b/xfa/fxfa/parser/cxfa_agent.h
index a84d2ac..8304a0e 100644
--- a/xfa/fxfa/parser/cxfa_agent.h
+++ b/xfa/fxfa/parser/cxfa_agent.h
@@ -11,8 +11,11 @@
 
 class CXFA_Agent final : public CXFA_Node {
  public:
-  CXFA_Agent(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Agent() override;
+
+ private:
+  CXFA_Agent(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_AGENT_H_
diff --git a/xfa/fxfa/parser/cxfa_alwaysembed.h b/xfa/fxfa/parser/cxfa_alwaysembed.h
index 754fd89..68e3c1f 100644
--- a/xfa/fxfa/parser/cxfa_alwaysembed.h
+++ b/xfa/fxfa/parser/cxfa_alwaysembed.h
@@ -11,8 +11,11 @@
 
 class CXFA_AlwaysEmbed final : public CXFA_Node {
  public:
-  CXFA_AlwaysEmbed(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AlwaysEmbed() override;
+
+ private:
+  CXFA_AlwaysEmbed(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ALWAYSEMBED_H_
diff --git a/xfa/fxfa/parser/cxfa_amd.h b/xfa/fxfa/parser/cxfa_amd.h
index 6d6562c..d60b35b 100644
--- a/xfa/fxfa/parser/cxfa_amd.h
+++ b/xfa/fxfa/parser/cxfa_amd.h
@@ -11,8 +11,11 @@
 
 class CXFA_Amd final : public CXFA_Node {
  public:
-  CXFA_Amd(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Amd() override;
+
+ private:
+  CXFA_Amd(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_AMD_H_
diff --git a/xfa/fxfa/parser/cxfa_appearancefilter.h b/xfa/fxfa/parser/cxfa_appearancefilter.h
index 80b0ba4..b56e267 100644
--- a/xfa/fxfa/parser/cxfa_appearancefilter.h
+++ b/xfa/fxfa/parser/cxfa_appearancefilter.h
@@ -11,8 +11,11 @@
 
 class CXFA_AppearanceFilter final : public CXFA_Node {
  public:
-  CXFA_AppearanceFilter(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AppearanceFilter() override;
+
+ private:
+  CXFA_AppearanceFilter(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_APPEARANCEFILTER_H_
diff --git a/xfa/fxfa/parser/cxfa_arc.h b/xfa/fxfa/parser/cxfa_arc.h
index 70d1b00..dee205b 100644
--- a/xfa/fxfa/parser/cxfa_arc.h
+++ b/xfa/fxfa/parser/cxfa_arc.h
@@ -11,8 +11,11 @@
 
 class CXFA_Arc final : public CXFA_Box {
  public:
-  CXFA_Arc(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Arc() override;
+
+ private:
+  CXFA_Arc(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ARC_H_
diff --git a/xfa/fxfa/parser/cxfa_area.h b/xfa/fxfa/parser/cxfa_area.h
index cf1ff87..7be84c9 100644
--- a/xfa/fxfa/parser/cxfa_area.h
+++ b/xfa/fxfa/parser/cxfa_area.h
@@ -11,8 +11,11 @@
 
 class CXFA_Area final : public CXFA_Node {
  public:
-  CXFA_Area(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Area() override;
+
+ private:
+  CXFA_Area(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_AREA_H_
diff --git a/xfa/fxfa/parser/cxfa_arraynodelist.cpp b/xfa/fxfa/parser/cxfa_arraynodelist.cpp
index cedf7ef..55c4123 100644
--- a/xfa/fxfa/parser/cxfa_arraynodelist.cpp
+++ b/xfa/fxfa/parser/cxfa_arraynodelist.cpp
@@ -9,14 +9,25 @@
 #include <utility>
 #include <vector>
 
+#include "xfa/fxfa/parser/cxfa_node.h"
+
 CXFA_ArrayNodeList::CXFA_ArrayNodeList(CXFA_Document* pDocument)
     : CXFA_TreeList(pDocument) {}
 
 CXFA_ArrayNodeList::~CXFA_ArrayNodeList() = default;
 
-void CXFA_ArrayNodeList::SetArrayNodeList(std::vector<CXFA_Node*> srcArray) {
-  if (!srcArray.empty())
-    m_array = std::move(srcArray);
+void CXFA_ArrayNodeList::Trace(cppgc::Visitor* visitor) const {
+  CXFA_TreeList::Trace(visitor);
+  for (const auto& node : m_array)
+    visitor->Trace(node);
+}
+
+void CXFA_ArrayNodeList::SetArrayNodeList(
+    const std::vector<CXFA_Node*>& srcArray) {
+  if (!srcArray.empty()) {
+    m_array =
+        std::vector<cppgc::Member<CXFA_Node>>(srcArray.begin(), srcArray.end());
+  }
 }
 
 size_t CXFA_ArrayNodeList::GetLength() {
diff --git a/xfa/fxfa/parser/cxfa_arraynodelist.h b/xfa/fxfa/parser/cxfa_arraynodelist.h
index 238c52c..1d50cf2 100644
--- a/xfa/fxfa/parser/cxfa_arraynodelist.h
+++ b/xfa/fxfa/parser/cxfa_arraynodelist.h
@@ -9,6 +9,8 @@
 
 #include <vector>
 
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/parser/cxfa_treelist.h"
 
 class CXFA_Document;
@@ -16,9 +18,11 @@
 
 class CXFA_ArrayNodeList final : public CXFA_TreeList {
  public:
-  explicit CXFA_ArrayNodeList(CXFA_Document* pDocument);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ArrayNodeList() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_TreeList:
   size_t GetLength() override;
   void Append(CXFA_Node* pNode) override;
@@ -26,10 +30,12 @@
   void Remove(CXFA_Node* pNode) override;
   CXFA_Node* Item(size_t iIndex) override;
 
-  void SetArrayNodeList(std::vector<CXFA_Node*> srcArray);
+  void SetArrayNodeList(const std::vector<CXFA_Node*>& srcArray);
 
  private:
-  std::vector<CXFA_Node*> m_array;
+  explicit CXFA_ArrayNodeList(CXFA_Document* pDocument);
+
+  std::vector<cppgc::Member<CXFA_Node>> m_array;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ARRAYNODELIST_H_
diff --git a/xfa/fxfa/parser/cxfa_assist.h b/xfa/fxfa/parser/cxfa_assist.h
index 77643cf..ff72002 100644
--- a/xfa/fxfa/parser/cxfa_assist.h
+++ b/xfa/fxfa/parser/cxfa_assist.h
@@ -11,8 +11,11 @@
 
 class CXFA_Assist final : public CXFA_Node {
  public:
-  CXFA_Assist(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Assist() override;
+
+ private:
+  CXFA_Assist(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ASSIST_H_
diff --git a/xfa/fxfa/parser/cxfa_attachnodelist.cpp b/xfa/fxfa/parser/cxfa_attachnodelist.cpp
index 6d8e5c3..9dc89ef 100644
--- a/xfa/fxfa/parser/cxfa_attachnodelist.cpp
+++ b/xfa/fxfa/parser/cxfa_attachnodelist.cpp
@@ -15,6 +15,11 @@
 
 CXFA_AttachNodeList::~CXFA_AttachNodeList() = default;
 
+void CXFA_AttachNodeList::Trace(cppgc::Visitor* visitor) const {
+  CXFA_TreeList::Trace(visitor);
+  visitor->Trace(m_pAttachNode);
+}
+
 size_t CXFA_AttachNodeList::GetLength() {
   return m_pAttachNode->CountChildren(
       XFA_Element::Unknown,
diff --git a/xfa/fxfa/parser/cxfa_attachnodelist.h b/xfa/fxfa/parser/cxfa_attachnodelist.h
index 2b20d70..f593426 100644
--- a/xfa/fxfa/parser/cxfa_attachnodelist.h
+++ b/xfa/fxfa/parser/cxfa_attachnodelist.h
@@ -7,6 +7,8 @@
 #ifndef XFA_FXFA_PARSER_CXFA_ATTACHNODELIST_H_
 #define XFA_FXFA_PARSER_CXFA_ATTACHNODELIST_H_
 
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/parser/cxfa_treelist.h"
 
 class CXFA_Document;
@@ -14,9 +16,11 @@
 
 class CXFA_AttachNodeList final : public CXFA_TreeList {
  public:
-  CXFA_AttachNodeList(CXFA_Document* pDocument, CXFA_Node* pAttachNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AttachNodeList() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_TreeList:
   size_t GetLength() override;
   void Append(CXFA_Node* pNode) override;
@@ -25,7 +29,9 @@
   CXFA_Node* Item(size_t iIndex) override;
 
  private:
-  UnownedPtr<CXFA_Node> const m_pAttachNode;
+  CXFA_AttachNodeList(CXFA_Document* pDocument, CXFA_Node* pAttachNode);
+
+  cppgc::Member<CXFA_Node> const m_pAttachNode;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ATTACHNODELIST_H_
diff --git a/xfa/fxfa/parser/cxfa_attributes.h b/xfa/fxfa/parser/cxfa_attributes.h
index 099ecea..5875ad2 100644
--- a/xfa/fxfa/parser/cxfa_attributes.h
+++ b/xfa/fxfa/parser/cxfa_attributes.h
@@ -11,8 +11,11 @@
 
 class CXFA_Attributes final : public CXFA_Node {
  public:
-  CXFA_Attributes(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Attributes() override;
+
+ private:
+  CXFA_Attributes(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ATTRIBUTES_H_
diff --git a/xfa/fxfa/parser/cxfa_autosave.h b/xfa/fxfa/parser/cxfa_autosave.h
index 5324351..1e96a68 100644
--- a/xfa/fxfa/parser/cxfa_autosave.h
+++ b/xfa/fxfa/parser/cxfa_autosave.h
@@ -11,8 +11,11 @@
 
 class CXFA_AutoSave final : public CXFA_Node {
  public:
-  CXFA_AutoSave(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_AutoSave() override;
+
+ private:
+  CXFA_AutoSave(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_AUTOSAVE_H_
diff --git a/xfa/fxfa/parser/cxfa_barcode.h b/xfa/fxfa/parser/cxfa_barcode.h
index 219e8b3..520e5d1 100644
--- a/xfa/fxfa/parser/cxfa_barcode.h
+++ b/xfa/fxfa/parser/cxfa_barcode.h
@@ -12,7 +12,7 @@
 
 class CXFA_Barcode final : public CXFA_Node {
  public:
-  CXFA_Barcode(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Barcode() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
@@ -30,6 +30,9 @@
   Optional<XFA_AttributeValue> GetTextLocation();
   Optional<bool> GetTruncate();
   Optional<int8_t> GetWideNarrowRatio();
+
+ private:
+  CXFA_Barcode(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BARCODE_H_
diff --git a/xfa/fxfa/parser/cxfa_base.h b/xfa/fxfa/parser/cxfa_base.h
index 3f1c9ba..508a7fd 100644
--- a/xfa/fxfa/parser/cxfa_base.h
+++ b/xfa/fxfa/parser/cxfa_base.h
@@ -11,8 +11,11 @@
 
 class CXFA_Base final : public CXFA_Node {
  public:
-  CXFA_Base(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Base() override;
+
+ private:
+  CXFA_Base(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BASE_H_
diff --git a/xfa/fxfa/parser/cxfa_batchoutput.h b/xfa/fxfa/parser/cxfa_batchoutput.h
index 8d1de09..c86a54a 100644
--- a/xfa/fxfa/parser/cxfa_batchoutput.h
+++ b/xfa/fxfa/parser/cxfa_batchoutput.h
@@ -11,8 +11,11 @@
 
 class CXFA_BatchOutput final : public CXFA_Node {
  public:
-  CXFA_BatchOutput(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_BatchOutput() override;
+
+ private:
+  CXFA_BatchOutput(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BATCHOUTPUT_H_
diff --git a/xfa/fxfa/parser/cxfa_behavioroverride.h b/xfa/fxfa/parser/cxfa_behavioroverride.h
index d7dce1b..8e9094a 100644
--- a/xfa/fxfa/parser/cxfa_behavioroverride.h
+++ b/xfa/fxfa/parser/cxfa_behavioroverride.h
@@ -11,8 +11,11 @@
 
 class CXFA_BehaviorOverride final : public CXFA_Node {
  public:
-  CXFA_BehaviorOverride(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_BehaviorOverride() override;
+
+ private:
+  CXFA_BehaviorOverride(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BEHAVIOROVERRIDE_H_
diff --git a/xfa/fxfa/parser/cxfa_bind.h b/xfa/fxfa/parser/cxfa_bind.h
index f6331d6..7045c88 100644
--- a/xfa/fxfa/parser/cxfa_bind.h
+++ b/xfa/fxfa/parser/cxfa_bind.h
@@ -11,10 +11,13 @@
 
 class CXFA_Bind final : public CXFA_Node {
  public:
-  CXFA_Bind(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Bind() override;
 
   WideString GetPicture();
+
+ private:
+  CXFA_Bind(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BIND_H_
diff --git a/xfa/fxfa/parser/cxfa_binditems.h b/xfa/fxfa/parser/cxfa_binditems.h
index 34a4b67..3d4b0f3 100644
--- a/xfa/fxfa/parser/cxfa_binditems.h
+++ b/xfa/fxfa/parser/cxfa_binditems.h
@@ -11,12 +11,15 @@
 
 class CXFA_BindItems final : public CXFA_Node {
  public:
-  CXFA_BindItems(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_BindItems() override;
 
   WideString GetLabelRef();
   WideString GetValueRef();
   WideString GetRef();
+
+ private:
+  CXFA_BindItems(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BINDITEMS_H_
diff --git a/xfa/fxfa/parser/cxfa_bookend.h b/xfa/fxfa/parser/cxfa_bookend.h
index 1c68763..c6f6541 100644
--- a/xfa/fxfa/parser/cxfa_bookend.h
+++ b/xfa/fxfa/parser/cxfa_bookend.h
@@ -11,8 +11,11 @@
 
 class CXFA_Bookend final : public CXFA_Node {
  public:
-  CXFA_Bookend(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Bookend() override;
+
+ private:
+  CXFA_Bookend(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BOOKEND_H_
diff --git a/xfa/fxfa/parser/cxfa_boolean.h b/xfa/fxfa/parser/cxfa_boolean.h
index 60b8e5e..f455d4a 100644
--- a/xfa/fxfa/parser/cxfa_boolean.h
+++ b/xfa/fxfa/parser/cxfa_boolean.h
@@ -11,8 +11,11 @@
 
 class CXFA_Boolean final : public CXFA_Node {
  public:
-  CXFA_Boolean(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Boolean() override;
+
+ private:
+  CXFA_Boolean(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BOOLEAN_H_
diff --git a/xfa/fxfa/parser/cxfa_border.h b/xfa/fxfa/parser/cxfa_border.h
index 6071a77..aa4e227 100644
--- a/xfa/fxfa/parser/cxfa_border.h
+++ b/xfa/fxfa/parser/cxfa_border.h
@@ -11,8 +11,11 @@
 
 class CXFA_Border final : public CXFA_Rectangle {
  public:
-  CXFA_Border(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Border() override;
+
+ private:
+  CXFA_Border(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BORDER_H_
diff --git a/xfa/fxfa/parser/cxfa_box.h b/xfa/fxfa/parser/cxfa_box.h
index cbda771..d72aad7 100644
--- a/xfa/fxfa/parser/cxfa_box.h
+++ b/xfa/fxfa/parser/cxfa_box.h
@@ -23,6 +23,7 @@
 
 class CXFA_Box : public CXFA_Node {
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Box() override;
 
   XFA_AttributeValue GetPresence();
diff --git a/xfa/fxfa/parser/cxfa_break.h b/xfa/fxfa/parser/cxfa_break.h
index 4bf7dde..63fdc8b 100644
--- a/xfa/fxfa/parser/cxfa_break.h
+++ b/xfa/fxfa/parser/cxfa_break.h
@@ -11,8 +11,11 @@
 
 class CXFA_Break final : public CXFA_Node {
  public:
-  CXFA_Break(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Break() override;
+
+ private:
+  CXFA_Break(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BREAK_H_
diff --git a/xfa/fxfa/parser/cxfa_breakafter.h b/xfa/fxfa/parser/cxfa_breakafter.h
index c607ef5..ca3d969 100644
--- a/xfa/fxfa/parser/cxfa_breakafter.h
+++ b/xfa/fxfa/parser/cxfa_breakafter.h
@@ -11,8 +11,11 @@
 
 class CXFA_BreakAfter final : public CXFA_Node {
  public:
-  CXFA_BreakAfter(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_BreakAfter() override;
+
+ private:
+  CXFA_BreakAfter(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BREAKAFTER_H_
diff --git a/xfa/fxfa/parser/cxfa_breakbefore.h b/xfa/fxfa/parser/cxfa_breakbefore.h
index 1b6dc63..58ada17 100644
--- a/xfa/fxfa/parser/cxfa_breakbefore.h
+++ b/xfa/fxfa/parser/cxfa_breakbefore.h
@@ -11,8 +11,11 @@
 
 class CXFA_BreakBefore final : public CXFA_Node {
  public:
-  CXFA_BreakBefore(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_BreakBefore() override;
+
+ private:
+  CXFA_BreakBefore(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BREAKBEFORE_H_
diff --git a/xfa/fxfa/parser/cxfa_button.h b/xfa/fxfa/parser/cxfa_button.h
index 1eddd65..56f25b6 100644
--- a/xfa/fxfa/parser/cxfa_button.h
+++ b/xfa/fxfa/parser/cxfa_button.h
@@ -11,12 +11,15 @@
 
 class CXFA_Button final : public CXFA_Node {
  public:
-  CXFA_Button(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Button() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
 
   XFA_AttributeValue GetHighlight();
+
+ private:
+  CXFA_Button(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_BUTTON_H_
diff --git a/xfa/fxfa/parser/cxfa_cache.h b/xfa/fxfa/parser/cxfa_cache.h
index 430163a..a02638e 100644
--- a/xfa/fxfa/parser/cxfa_cache.h
+++ b/xfa/fxfa/parser/cxfa_cache.h
@@ -11,8 +11,11 @@
 
 class CXFA_Cache final : public CXFA_Node {
  public:
-  CXFA_Cache(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Cache() override;
+
+ private:
+  CXFA_Cache(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CACHE_H_
diff --git a/xfa/fxfa/parser/cxfa_calculate.h b/xfa/fxfa/parser/cxfa_calculate.h
index a3934ac..34a4e58 100644
--- a/xfa/fxfa/parser/cxfa_calculate.h
+++ b/xfa/fxfa/parser/cxfa_calculate.h
@@ -13,12 +13,15 @@
 
 class CXFA_Calculate final : public CXFA_Node {
  public:
-  CXFA_Calculate(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Calculate() override;
 
   XFA_AttributeValue GetOverride();
   CXFA_Script* GetScriptIfExists();
   WideString GetMessageText();
+
+ private:
+  CXFA_Calculate(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CALCULATE_H_
diff --git a/xfa/fxfa/parser/cxfa_calendarsymbols.h b/xfa/fxfa/parser/cxfa_calendarsymbols.h
index 82ecde4..ad96c44 100644
--- a/xfa/fxfa/parser/cxfa_calendarsymbols.h
+++ b/xfa/fxfa/parser/cxfa_calendarsymbols.h
@@ -11,8 +11,11 @@
 
 class CXFA_CalendarSymbols final : public CXFA_Node {
  public:
-  CXFA_CalendarSymbols(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CalendarSymbols() override;
+
+ private:
+  CXFA_CalendarSymbols(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CALENDARSYMBOLS_H_
diff --git a/xfa/fxfa/parser/cxfa_caption.h b/xfa/fxfa/parser/cxfa_caption.h
index 9e7d38a..0d669b3 100644
--- a/xfa/fxfa/parser/cxfa_caption.h
+++ b/xfa/fxfa/parser/cxfa_caption.h
@@ -18,7 +18,7 @@
   static constexpr XFA_AttributeValue kDefaultPlacementType =
       XFA_AttributeValue::Left;
 
-  CXFA_Caption(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Caption() override;
 
   bool IsVisible();
@@ -28,6 +28,9 @@
   CXFA_Margin* GetMarginIfExists();
   CXFA_Font* GetFontIfExists();
   CXFA_Value* GetValueIfExists();
+
+ private:
+  CXFA_Caption(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CAPTION_H_
diff --git a/xfa/fxfa/parser/cxfa_certificate.h b/xfa/fxfa/parser/cxfa_certificate.h
index 4923d57..bf2aa34 100644
--- a/xfa/fxfa/parser/cxfa_certificate.h
+++ b/xfa/fxfa/parser/cxfa_certificate.h
@@ -11,8 +11,11 @@
 
 class CXFA_Certificate final : public CXFA_Node {
  public:
-  CXFA_Certificate(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Certificate() override;
+
+ private:
+  CXFA_Certificate(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CERTIFICATE_H_
diff --git a/xfa/fxfa/parser/cxfa_certificates.h b/xfa/fxfa/parser/cxfa_certificates.h
index 6817d03..0177fdc 100644
--- a/xfa/fxfa/parser/cxfa_certificates.h
+++ b/xfa/fxfa/parser/cxfa_certificates.h
@@ -11,8 +11,11 @@
 
 class CXFA_Certificates final : public CXFA_Node {
  public:
-  CXFA_Certificates(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Certificates() override;
+
+ private:
+  CXFA_Certificates(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CERTIFICATES_H_
diff --git a/xfa/fxfa/parser/cxfa_change.h b/xfa/fxfa/parser/cxfa_change.h
index 2fa4ba9..48ca13b 100644
--- a/xfa/fxfa/parser/cxfa_change.h
+++ b/xfa/fxfa/parser/cxfa_change.h
@@ -11,8 +11,11 @@
 
 class CXFA_Change final : public CXFA_Node {
  public:
-  CXFA_Change(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Change() override;
+
+ private:
+  CXFA_Change(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CHANGE_H_
diff --git a/xfa/fxfa/parser/cxfa_checkbutton.h b/xfa/fxfa/parser/cxfa_checkbutton.h
index 3ca8b9e..e2eb482 100644
--- a/xfa/fxfa/parser/cxfa_checkbutton.h
+++ b/xfa/fxfa/parser/cxfa_checkbutton.h
@@ -11,7 +11,7 @@
 
 class CXFA_CheckButton final : public CXFA_Node {
  public:
-  CXFA_CheckButton(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CheckButton() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
@@ -19,6 +19,9 @@
   bool IsRound();
   bool IsAllowNeutral();
   XFA_AttributeValue GetMark();
+
+ private:
+  CXFA_CheckButton(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CHECKBUTTON_H_
diff --git a/xfa/fxfa/parser/cxfa_choicelist.h b/xfa/fxfa/parser/cxfa_choicelist.h
index cff1463..c176f60 100644
--- a/xfa/fxfa/parser/cxfa_choicelist.h
+++ b/xfa/fxfa/parser/cxfa_choicelist.h
@@ -11,11 +11,14 @@
 
 class CXFA_ChoiceList final : public CXFA_Node {
  public:
-  CXFA_ChoiceList(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ChoiceList() override;
 
   XFA_Element GetValueNodeType() const override;
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_ChoiceList(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CHOICELIST_H_
diff --git a/xfa/fxfa/parser/cxfa_color.h b/xfa/fxfa/parser/cxfa_color.h
index d13a553..32706e9 100644
--- a/xfa/fxfa/parser/cxfa_color.h
+++ b/xfa/fxfa/parser/cxfa_color.h
@@ -13,12 +13,15 @@
  public:
   static constexpr FX_ARGB kBlackColor = 0xFF000000;
 
-  CXFA_Color(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Color() override;
 
   FX_ARGB GetValue();
   FX_ARGB GetValueOrDefault(FX_ARGB defaultValue);
   void SetValue(FX_ARGB color);
+
+ private:
+  CXFA_Color(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COLOR_H_
diff --git a/xfa/fxfa/parser/cxfa_comb.h b/xfa/fxfa/parser/cxfa_comb.h
index 4193a9c..1c2c27e 100644
--- a/xfa/fxfa/parser/cxfa_comb.h
+++ b/xfa/fxfa/parser/cxfa_comb.h
@@ -11,8 +11,11 @@
 
 class CXFA_Comb final : public CXFA_Node {
  public:
-  CXFA_Comb(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Comb() override;
+
+ private:
+  CXFA_Comb(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMB_H_
diff --git a/xfa/fxfa/parser/cxfa_command.h b/xfa/fxfa/parser/cxfa_command.h
index 46f9854..2a0068f 100644
--- a/xfa/fxfa/parser/cxfa_command.h
+++ b/xfa/fxfa/parser/cxfa_command.h
@@ -11,8 +11,11 @@
 
 class CXFA_Command final : public CXFA_Node {
  public:
-  CXFA_Command(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Command() override;
+
+ private:
+  CXFA_Command(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMMAND_H_
diff --git a/xfa/fxfa/parser/cxfa_common.h b/xfa/fxfa/parser/cxfa_common.h
index 7cab852..b98c7b0 100644
--- a/xfa/fxfa/parser/cxfa_common.h
+++ b/xfa/fxfa/parser/cxfa_common.h
@@ -11,8 +11,11 @@
 
 class CXFA_Common final : public CXFA_Node {
  public:
-  CXFA_Common(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Common() override;
+
+ private:
+  CXFA_Common(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMMON_H_
diff --git a/xfa/fxfa/parser/cxfa_compress.h b/xfa/fxfa/parser/cxfa_compress.h
index 2b56390..6e7532f 100644
--- a/xfa/fxfa/parser/cxfa_compress.h
+++ b/xfa/fxfa/parser/cxfa_compress.h
@@ -11,8 +11,11 @@
 
 class CXFA_Compress final : public CXFA_Node {
  public:
-  CXFA_Compress(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Compress() override;
+
+ private:
+  CXFA_Compress(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMPRESS_H_
diff --git a/xfa/fxfa/parser/cxfa_compression.h b/xfa/fxfa/parser/cxfa_compression.h
index 7a571ae..657b911 100644
--- a/xfa/fxfa/parser/cxfa_compression.h
+++ b/xfa/fxfa/parser/cxfa_compression.h
@@ -11,8 +11,11 @@
 
 class CXFA_Compression final : public CXFA_Node {
  public:
-  CXFA_Compression(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Compression() override;
+
+ private:
+  CXFA_Compression(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMPRESSION_H_
diff --git a/xfa/fxfa/parser/cxfa_compresslogicalstructure.h b/xfa/fxfa/parser/cxfa_compresslogicalstructure.h
index 843eb60..8cefac6 100644
--- a/xfa/fxfa/parser/cxfa_compresslogicalstructure.h
+++ b/xfa/fxfa/parser/cxfa_compresslogicalstructure.h
@@ -11,8 +11,11 @@
 
 class CXFA_CompressLogicalStructure final : public CXFA_Node {
  public:
-  CXFA_CompressLogicalStructure(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CompressLogicalStructure() override;
+
+ private:
+  CXFA_CompressLogicalStructure(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMPRESSLOGICALSTRUCTURE_H_
diff --git a/xfa/fxfa/parser/cxfa_compressobjectstream.h b/xfa/fxfa/parser/cxfa_compressobjectstream.h
index bce7c65..1807c7c 100644
--- a/xfa/fxfa/parser/cxfa_compressobjectstream.h
+++ b/xfa/fxfa/parser/cxfa_compressobjectstream.h
@@ -11,8 +11,11 @@
 
 class CXFA_CompressObjectStream final : public CXFA_Node {
  public:
-  CXFA_CompressObjectStream(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CompressObjectStream() override;
+
+ private:
+  CXFA_CompressObjectStream(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COMPRESSOBJECTSTREAM_H_
diff --git a/xfa/fxfa/parser/cxfa_config.h b/xfa/fxfa/parser/cxfa_config.h
index 644c475..f7c2185 100644
--- a/xfa/fxfa/parser/cxfa_config.h
+++ b/xfa/fxfa/parser/cxfa_config.h
@@ -11,8 +11,11 @@
 
 class CXFA_Config final : public CXFA_Node {
  public:
-  CXFA_Config(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Config() override;
+
+ private:
+  CXFA_Config(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONFIG_H_
diff --git a/xfa/fxfa/parser/cxfa_conformance.h b/xfa/fxfa/parser/cxfa_conformance.h
index 829bb1c..e775319 100644
--- a/xfa/fxfa/parser/cxfa_conformance.h
+++ b/xfa/fxfa/parser/cxfa_conformance.h
@@ -11,8 +11,11 @@
 
 class CXFA_Conformance final : public CXFA_Node {
  public:
-  CXFA_Conformance(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Conformance() override;
+
+ private:
+  CXFA_Conformance(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONFORMANCE_H_
diff --git a/xfa/fxfa/parser/cxfa_connect.h b/xfa/fxfa/parser/cxfa_connect.h
index 3d616ce..ec551fc 100644
--- a/xfa/fxfa/parser/cxfa_connect.h
+++ b/xfa/fxfa/parser/cxfa_connect.h
@@ -11,8 +11,11 @@
 
 class CXFA_Connect final : public CXFA_Node {
  public:
-  CXFA_Connect(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Connect() override;
+
+ private:
+  CXFA_Connect(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONNECT_H_
diff --git a/xfa/fxfa/parser/cxfa_connectionset.h b/xfa/fxfa/parser/cxfa_connectionset.h
index 74238e0..b816fca 100644
--- a/xfa/fxfa/parser/cxfa_connectionset.h
+++ b/xfa/fxfa/parser/cxfa_connectionset.h
@@ -11,8 +11,11 @@
 
 class CXFA_ConnectionSet final : public CXFA_Node {
  public:
-  CXFA_ConnectionSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ConnectionSet() override;
+
+ private:
+  CXFA_ConnectionSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONNECTIONSET_H_
diff --git a/xfa/fxfa/parser/cxfa_connectstring.h b/xfa/fxfa/parser/cxfa_connectstring.h
index 88dd7bc..3a56a11 100644
--- a/xfa/fxfa/parser/cxfa_connectstring.h
+++ b/xfa/fxfa/parser/cxfa_connectstring.h
@@ -11,8 +11,11 @@
 
 class CXFA_ConnectString final : public CXFA_Node {
  public:
-  CXFA_ConnectString(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ConnectString() override;
+
+ private:
+  CXFA_ConnectString(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONNECTSTRING_H_
diff --git a/xfa/fxfa/parser/cxfa_contentarea.h b/xfa/fxfa/parser/cxfa_contentarea.h
index 43f6868..6eb4d6c 100644
--- a/xfa/fxfa/parser/cxfa_contentarea.h
+++ b/xfa/fxfa/parser/cxfa_contentarea.h
@@ -11,8 +11,11 @@
 
 class CXFA_ContentArea final : public CXFA_Node {
  public:
-  CXFA_ContentArea(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ContentArea() override;
+
+ private:
+  CXFA_ContentArea(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONTENTAREA_H_
diff --git a/xfa/fxfa/parser/cxfa_contentcopy.h b/xfa/fxfa/parser/cxfa_contentcopy.h
index 5b32beb..f00c811 100644
--- a/xfa/fxfa/parser/cxfa_contentcopy.h
+++ b/xfa/fxfa/parser/cxfa_contentcopy.h
@@ -11,8 +11,11 @@
 
 class CXFA_ContentCopy final : public CXFA_Node {
  public:
-  CXFA_ContentCopy(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ContentCopy() override;
+
+ private:
+  CXFA_ContentCopy(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONTENTCOPY_H_
diff --git a/xfa/fxfa/parser/cxfa_copies.h b/xfa/fxfa/parser/cxfa_copies.h
index 46497f9..6c6b5ab 100644
--- a/xfa/fxfa/parser/cxfa_copies.h
+++ b/xfa/fxfa/parser/cxfa_copies.h
@@ -11,8 +11,11 @@
 
 class CXFA_Copies final : public CXFA_Node {
  public:
-  CXFA_Copies(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Copies() override;
+
+ private:
+  CXFA_Copies(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_COPIES_H_
diff --git a/xfa/fxfa/parser/cxfa_corner.h b/xfa/fxfa/parser/cxfa_corner.h
index 7dcaf32..4a18d26 100644
--- a/xfa/fxfa/parser/cxfa_corner.h
+++ b/xfa/fxfa/parser/cxfa_corner.h
@@ -11,8 +11,11 @@
 
 class CXFA_Corner final : public CXFA_Stroke {
  public:
-  CXFA_Corner(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Corner() override;
+
+ private:
+  CXFA_Corner(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CORNER_H_
diff --git a/xfa/fxfa/parser/cxfa_creator.h b/xfa/fxfa/parser/cxfa_creator.h
index 437fab5..6e3f98e 100644
--- a/xfa/fxfa/parser/cxfa_creator.h
+++ b/xfa/fxfa/parser/cxfa_creator.h
@@ -11,8 +11,11 @@
 
 class CXFA_Creator final : public CXFA_Node {
  public:
-  CXFA_Creator(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Creator() override;
+
+ private:
+  CXFA_Creator(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CREATOR_H_
diff --git a/xfa/fxfa/parser/cxfa_currencysymbol.h b/xfa/fxfa/parser/cxfa_currencysymbol.h
index 3d7b5bd..87009f8 100644
--- a/xfa/fxfa/parser/cxfa_currencysymbol.h
+++ b/xfa/fxfa/parser/cxfa_currencysymbol.h
@@ -11,8 +11,11 @@
 
 class CXFA_CurrencySymbol final : public CXFA_Node {
  public:
-  CXFA_CurrencySymbol(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CurrencySymbol() override;
+
+ private:
+  CXFA_CurrencySymbol(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CURRENCYSYMBOL_H_
diff --git a/xfa/fxfa/parser/cxfa_currencysymbols.h b/xfa/fxfa/parser/cxfa_currencysymbols.h
index 2ce27cf..5b51a04 100644
--- a/xfa/fxfa/parser/cxfa_currencysymbols.h
+++ b/xfa/fxfa/parser/cxfa_currencysymbols.h
@@ -11,8 +11,11 @@
 
 class CXFA_CurrencySymbols final : public CXFA_Node {
  public:
-  CXFA_CurrencySymbols(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CurrencySymbols() override;
+
+ private:
+  CXFA_CurrencySymbols(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CURRENCYSYMBOLS_H_
diff --git a/xfa/fxfa/parser/cxfa_currentpage.h b/xfa/fxfa/parser/cxfa_currentpage.h
index 5bba6a0..666d874 100644
--- a/xfa/fxfa/parser/cxfa_currentpage.h
+++ b/xfa/fxfa/parser/cxfa_currentpage.h
@@ -11,8 +11,11 @@
 
 class CXFA_CurrentPage final : public CXFA_Node {
  public:
-  CXFA_CurrentPage(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_CurrentPage() override;
+
+ private:
+  CXFA_CurrentPage(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_CURRENTPAGE_H_
diff --git a/xfa/fxfa/parser/cxfa_data.h b/xfa/fxfa/parser/cxfa_data.h
index 44cf40d..b5ee346 100644
--- a/xfa/fxfa/parser/cxfa_data.h
+++ b/xfa/fxfa/parser/cxfa_data.h
@@ -11,8 +11,11 @@
 
 class CXFA_Data final : public CXFA_Node {
  public:
-  CXFA_Data(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Data() override;
+
+ private:
+  CXFA_Data(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATA_H_
diff --git a/xfa/fxfa/parser/cxfa_datagroup.h b/xfa/fxfa/parser/cxfa_datagroup.h
index 5a61704..088a2ea 100644
--- a/xfa/fxfa/parser/cxfa_datagroup.h
+++ b/xfa/fxfa/parser/cxfa_datagroup.h
@@ -11,8 +11,11 @@
 
 class CXFA_DataGroup final : public CXFA_Node {
  public:
-  CXFA_DataGroup(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DataGroup() override;
+
+ private:
+  CXFA_DataGroup(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATAGROUP_H_
diff --git a/xfa/fxfa/parser/cxfa_datamodel.h b/xfa/fxfa/parser/cxfa_datamodel.h
index 8a1bd42..4f34419 100644
--- a/xfa/fxfa/parser/cxfa_datamodel.h
+++ b/xfa/fxfa/parser/cxfa_datamodel.h
@@ -11,8 +11,11 @@
 
 class CXFA_DataModel final : public CXFA_Node {
  public:
-  CXFA_DataModel(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DataModel() override;
+
+ private:
+  CXFA_DataModel(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATAMODEL_H_
diff --git a/xfa/fxfa/parser/cxfa_datavalue.h b/xfa/fxfa/parser/cxfa_datavalue.h
index ee2c621..b433521 100644
--- a/xfa/fxfa/parser/cxfa_datavalue.h
+++ b/xfa/fxfa/parser/cxfa_datavalue.h
@@ -11,8 +11,11 @@
 
 class CXFA_DataValue final : public CXFA_Node {
  public:
-  CXFA_DataValue(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DataValue() override;
+
+ private:
+  CXFA_DataValue(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATAVALUE_H_
diff --git a/xfa/fxfa/parser/cxfa_date.h b/xfa/fxfa/parser/cxfa_date.h
index 3fb7ba7..9369e10 100644
--- a/xfa/fxfa/parser/cxfa_date.h
+++ b/xfa/fxfa/parser/cxfa_date.h
@@ -11,8 +11,11 @@
 
 class CXFA_Date final : public CXFA_Node {
  public:
-  CXFA_Date(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Date() override;
+
+ private:
+  CXFA_Date(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATE_H_
diff --git a/xfa/fxfa/parser/cxfa_datepattern.h b/xfa/fxfa/parser/cxfa_datepattern.h
index e67a61f..914829f 100644
--- a/xfa/fxfa/parser/cxfa_datepattern.h
+++ b/xfa/fxfa/parser/cxfa_datepattern.h
@@ -11,8 +11,11 @@
 
 class CXFA_DatePattern final : public CXFA_Node {
  public:
-  CXFA_DatePattern(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DatePattern() override;
+
+ private:
+  CXFA_DatePattern(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATEPATTERN_H_
diff --git a/xfa/fxfa/parser/cxfa_datepatterns.h b/xfa/fxfa/parser/cxfa_datepatterns.h
index 6c2dca4..02838d0 100644
--- a/xfa/fxfa/parser/cxfa_datepatterns.h
+++ b/xfa/fxfa/parser/cxfa_datepatterns.h
@@ -11,8 +11,11 @@
 
 class CXFA_DatePatterns final : public CXFA_Node {
  public:
-  CXFA_DatePatterns(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DatePatterns() override;
+
+ private:
+  CXFA_DatePatterns(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATEPATTERNS_H_
diff --git a/xfa/fxfa/parser/cxfa_datetime.h b/xfa/fxfa/parser/cxfa_datetime.h
index ca71daf..56d1cd8 100644
--- a/xfa/fxfa/parser/cxfa_datetime.h
+++ b/xfa/fxfa/parser/cxfa_datetime.h
@@ -11,8 +11,11 @@
 
 class CXFA_DateTime final : public CXFA_Node {
  public:
-  CXFA_DateTime(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DateTime() override;
+
+ private:
+  CXFA_DateTime(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATETIME_H_
diff --git a/xfa/fxfa/parser/cxfa_datetimeedit.h b/xfa/fxfa/parser/cxfa_datetimeedit.h
index de76e2a..7fa7248 100644
--- a/xfa/fxfa/parser/cxfa_datetimeedit.h
+++ b/xfa/fxfa/parser/cxfa_datetimeedit.h
@@ -11,11 +11,14 @@
 
 class CXFA_DateTimeEdit final : public CXFA_Node {
  public:
-  CXFA_DateTimeEdit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DateTimeEdit() override;
 
   XFA_Element GetValueNodeType() const override;
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_DateTimeEdit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATETIMEEDIT_H_
diff --git a/xfa/fxfa/parser/cxfa_datetimesymbols.h b/xfa/fxfa/parser/cxfa_datetimesymbols.h
index cfbe069..e543f0c 100644
--- a/xfa/fxfa/parser/cxfa_datetimesymbols.h
+++ b/xfa/fxfa/parser/cxfa_datetimesymbols.h
@@ -11,8 +11,11 @@
 
 class CXFA_DateTimeSymbols final : public CXFA_Node {
  public:
-  CXFA_DateTimeSymbols(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DateTimeSymbols() override;
+
+ private:
+  CXFA_DateTimeSymbols(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DATETIMESYMBOLS_H_
diff --git a/xfa/fxfa/parser/cxfa_day.h b/xfa/fxfa/parser/cxfa_day.h
index 6fb2f45..b87aa17 100644
--- a/xfa/fxfa/parser/cxfa_day.h
+++ b/xfa/fxfa/parser/cxfa_day.h
@@ -11,8 +11,11 @@
 
 class CXFA_Day final : public CXFA_Node {
  public:
-  CXFA_Day(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Day() override;
+
+ private:
+  CXFA_Day(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DAY_H_
diff --git a/xfa/fxfa/parser/cxfa_daynames.h b/xfa/fxfa/parser/cxfa_daynames.h
index 229d69c..296f371 100644
--- a/xfa/fxfa/parser/cxfa_daynames.h
+++ b/xfa/fxfa/parser/cxfa_daynames.h
@@ -11,8 +11,11 @@
 
 class CXFA_DayNames final : public CXFA_Node {
  public:
-  CXFA_DayNames(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DayNames() override;
+
+ private:
+  CXFA_DayNames(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DAYNAMES_H_
diff --git a/xfa/fxfa/parser/cxfa_debug.h b/xfa/fxfa/parser/cxfa_debug.h
index 1a254f0..fa3546d 100644
--- a/xfa/fxfa/parser/cxfa_debug.h
+++ b/xfa/fxfa/parser/cxfa_debug.h
@@ -11,8 +11,11 @@
 
 class CXFA_Debug final : public CXFA_Node {
  public:
-  CXFA_Debug(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Debug() override;
+
+ private:
+  CXFA_Debug(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DEBUG_H_
diff --git a/xfa/fxfa/parser/cxfa_decimal.h b/xfa/fxfa/parser/cxfa_decimal.h
index 668f61a..d1ad08b 100644
--- a/xfa/fxfa/parser/cxfa_decimal.h
+++ b/xfa/fxfa/parser/cxfa_decimal.h
@@ -11,8 +11,11 @@
 
 class CXFA_Decimal final : public CXFA_Node {
  public:
-  CXFA_Decimal(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Decimal() override;
+
+ private:
+  CXFA_Decimal(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DECIMAL_H_
diff --git a/xfa/fxfa/parser/cxfa_defaulttypeface.h b/xfa/fxfa/parser/cxfa_defaulttypeface.h
index a241bf8..ccbc306 100644
--- a/xfa/fxfa/parser/cxfa_defaulttypeface.h
+++ b/xfa/fxfa/parser/cxfa_defaulttypeface.h
@@ -11,8 +11,11 @@
 
 class CXFA_DefaultTypeface final : public CXFA_Node {
  public:
-  CXFA_DefaultTypeface(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DefaultTypeface() override;
+
+ private:
+  CXFA_DefaultTypeface(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DEFAULTTYPEFACE_H_
diff --git a/xfa/fxfa/parser/cxfa_defaultui.h b/xfa/fxfa/parser/cxfa_defaultui.h
index d09da0b..a63dca5 100644
--- a/xfa/fxfa/parser/cxfa_defaultui.h
+++ b/xfa/fxfa/parser/cxfa_defaultui.h
@@ -11,10 +11,13 @@
 
 class CXFA_DefaultUi final : public CXFA_Node {
  public:
-  CXFA_DefaultUi(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DefaultUi() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_DefaultUi(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DEFAULTUI_H_
diff --git a/xfa/fxfa/parser/cxfa_delete.h b/xfa/fxfa/parser/cxfa_delete.h
index 0ea6ab3..89e7035 100644
--- a/xfa/fxfa/parser/cxfa_delete.h
+++ b/xfa/fxfa/parser/cxfa_delete.h
@@ -11,8 +11,11 @@
 
 class CXFA_Delete final : public CXFA_Node {
  public:
-  CXFA_Delete(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Delete() override;
+
+ private:
+  CXFA_Delete(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DELETE_H_
diff --git a/xfa/fxfa/parser/cxfa_delta.h b/xfa/fxfa/parser/cxfa_delta.h
index 40bfa56..a68299b 100644
--- a/xfa/fxfa/parser/cxfa_delta.h
+++ b/xfa/fxfa/parser/cxfa_delta.h
@@ -11,8 +11,11 @@
 
 class CXFA_Delta final : public CXFA_Node {
  public:
-  CXFA_Delta(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Delta() override;
+
+ private:
+  CXFA_Delta(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DELTA_H_
diff --git a/xfa/fxfa/parser/cxfa_desc.h b/xfa/fxfa/parser/cxfa_desc.h
index 11baa90..2c69f47 100644
--- a/xfa/fxfa/parser/cxfa_desc.h
+++ b/xfa/fxfa/parser/cxfa_desc.h
@@ -11,8 +11,11 @@
 
 class CXFA_Desc final : public CXFA_Node {
  public:
-  CXFA_Desc(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Desc() override;
+
+ private:
+  CXFA_Desc(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DESC_H_
diff --git a/xfa/fxfa/parser/cxfa_destination.h b/xfa/fxfa/parser/cxfa_destination.h
index d31434f..de06f85 100644
--- a/xfa/fxfa/parser/cxfa_destination.h
+++ b/xfa/fxfa/parser/cxfa_destination.h
@@ -11,8 +11,11 @@
 
 class CXFA_Destination final : public CXFA_Node {
  public:
-  CXFA_Destination(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Destination() override;
+
+ private:
+  CXFA_Destination(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DESTINATION_H_
diff --git a/xfa/fxfa/parser/cxfa_digestmethod.h b/xfa/fxfa/parser/cxfa_digestmethod.h
index 777f46a..10541fd 100644
--- a/xfa/fxfa/parser/cxfa_digestmethod.h
+++ b/xfa/fxfa/parser/cxfa_digestmethod.h
@@ -11,8 +11,11 @@
 
 class CXFA_DigestMethod final : public CXFA_Node {
  public:
-  CXFA_DigestMethod(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DigestMethod() override;
+
+ private:
+  CXFA_DigestMethod(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DIGESTMETHOD_H_
diff --git a/xfa/fxfa/parser/cxfa_digestmethods.h b/xfa/fxfa/parser/cxfa_digestmethods.h
index 61dac97..759db42 100644
--- a/xfa/fxfa/parser/cxfa_digestmethods.h
+++ b/xfa/fxfa/parser/cxfa_digestmethods.h
@@ -11,8 +11,11 @@
 
 class CXFA_DigestMethods final : public CXFA_Node {
  public:
-  CXFA_DigestMethods(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DigestMethods() override;
+
+ private:
+  CXFA_DigestMethods(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DIGESTMETHODS_H_
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 4a6a51d..ff18694 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -1274,9 +1274,12 @@
 }  // namespace
 
 CXFA_Document::CXFA_Document(CXFA_FFNotify* notify,
-                             std::unique_ptr<LayoutProcessorIface> pLayout)
-    : CXFA_NodeOwner(),
+                             cppgc::Heap* heap,
+                             LayoutProcessorIface* pLayout)
+    : heap_(heap),
       notify_(notify),
+      node_owner_(cppgc::MakeGarbageCollected<CXFA_NodeOwner>(
+          heap->GetAllocationHandle())),
       m_pLayoutProcessor(std::move(pLayout)) {
   if (m_pLayoutProcessor)
     m_pLayoutProcessor->SetDocument(this);
@@ -1284,16 +1287,31 @@
 
 CXFA_Document::~CXFA_Document() = default;
 
+void CXFA_Document::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(notify_);
+  visitor->Trace(node_owner_);
+  visitor->Trace(m_pRootNode);
+  visitor->Trace(m_pLayoutProcessor);
+  visitor->Trace(m_pScriptDataWindow);
+  visitor->Trace(m_pScriptEvent);
+  visitor->Trace(m_pScriptHost);
+  visitor->Trace(m_pScriptLog);
+  visitor->Trace(m_pScriptLayout);
+  visitor->Trace(m_pScriptSignature);
+  for (const auto& binding : m_rgGlobalBinding)
+    visitor->Trace(binding.second);
+}
+
 void CXFA_Document::ClearLayoutData() {
-  m_pLayoutProcessor.reset();
+  m_pLayoutProcessor = nullptr;
   m_pScriptContext.reset();
   m_pLocaleMgr.reset();
-  m_pScriptDataWindow.reset();
-  m_pScriptEvent.reset();
-  m_pScriptHost.reset();
-  m_pScriptLog.reset();
-  m_pScriptLayout.reset();
-  m_pScriptSignature.reset();
+  m_pScriptDataWindow = nullptr;
+  m_pScriptEvent = nullptr;
+  m_pScriptHost = nullptr;
+  m_pScriptLog = nullptr;
+  m_pScriptLayout = nullptr;
+  m_pScriptSignature = nullptr;
 }
 
 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) {
@@ -1335,34 +1353,41 @@
     }
     case XFA_HASHCODE_DataWindow: {
       if (!m_pScriptDataWindow)
-        m_pScriptDataWindow = std::make_unique<CScript_DataWindow>(this);
-      return m_pScriptDataWindow.get();
+        m_pScriptDataWindow = cppgc::MakeGarbageCollected<CScript_DataWindow>(
+            GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptDataWindow;
     }
     case XFA_HASHCODE_Event: {
       if (!m_pScriptEvent)
-        m_pScriptEvent = std::make_unique<CScript_EventPseudoModel>(this);
-      return m_pScriptEvent.get();
+        m_pScriptEvent = cppgc::MakeGarbageCollected<CScript_EventPseudoModel>(
+            GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptEvent;
     }
     case XFA_HASHCODE_Host: {
       if (!m_pScriptHost)
-        m_pScriptHost = std::make_unique<CScript_HostPseudoModel>(this);
-      return m_pScriptHost.get();
+        m_pScriptHost = cppgc::MakeGarbageCollected<CScript_HostPseudoModel>(
+            GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptHost;
     }
     case XFA_HASHCODE_Log: {
       if (!m_pScriptLog)
-        m_pScriptLog = std::make_unique<CScript_LogPseudoModel>(this);
-      return m_pScriptLog.get();
+        m_pScriptLog = cppgc::MakeGarbageCollected<CScript_LogPseudoModel>(
+            GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptLog;
     }
     case XFA_HASHCODE_Signature: {
       if (!m_pScriptSignature)
         m_pScriptSignature =
-            std::make_unique<CScript_SignaturePseudoModel>(this);
-      return m_pScriptSignature.get();
+            cppgc::MakeGarbageCollected<CScript_SignaturePseudoModel>(
+                GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptSignature;
     }
     case XFA_HASHCODE_Layout: {
       if (!m_pScriptLayout)
-        m_pScriptLayout = std::make_unique<CScript_LayoutPseudoModel>(this);
-      return m_pScriptLayout.get();
+        m_pScriptLayout =
+            cppgc::MakeGarbageCollected<CScript_LayoutPseudoModel>(
+                GetHeap()->GetAllocationHandle(), this);
+      return m_pScriptLayout;
     }
     default:
       return m_pRootNode->GetFirstChildByName(dwNodeNameHash);
@@ -1373,7 +1398,8 @@
                                      XFA_Element eElement) {
   if (eElement == XFA_Element::Unknown)
     return nullptr;
-  return AddOwnedNode(CXFA_Node::Create(this, eElement, packet));
+
+  return CXFA_Node::Create(this, eElement, packet);
 }
 
 bool CXFA_Document::IsInteractive() {
@@ -1414,7 +1440,7 @@
 }
 
 cppgc::Heap* CXFA_Document::GetHeap() const {
-  return notify_->GetFFDoc()->GetHeap();
+  return heap_.Get();
 }
 
 CFXJSE_Engine* CXFA_Document::InitScriptContext(CJS_Runtime* fxjs_runtime) {
@@ -1832,3 +1858,7 @@
 CXFA_Document::LayoutProcessorIface::LayoutProcessorIface() = default;
 
 CXFA_Document::LayoutProcessorIface::~LayoutProcessorIface() = default;
+
+void CXFA_Document::LayoutProcessorIface::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDocument);
+}
diff --git a/xfa/fxfa/parser/cxfa_document.h b/xfa/fxfa/parser/cxfa_document.h
index c9fa4bf..1cfe70e 100644
--- a/xfa/fxfa/parser/cxfa_document.h
+++ b/xfa/fxfa/parser/cxfa_document.h
@@ -12,7 +12,12 @@
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/heap.h"
 #include "third_party/base/optional.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/persistent.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_localemgr.h"
 #include "xfa/fxfa/parser/cxfa_nodeowner.h"
@@ -51,25 +56,29 @@
   XFA_VERSION_MAX = 400,
 };
 
-class CXFA_Document final : public CXFA_NodeOwner {
+class CXFA_Document final : public cppgc::GarbageCollected<CXFA_Document> {
  public:
-  class LayoutProcessorIface {
+  class LayoutProcessorIface
+      : public cppgc::GarbageCollected<LayoutProcessorIface> {
    public:
     LayoutProcessorIface();
     virtual ~LayoutProcessorIface();
+
+    virtual void Trace(cppgc::Visitor* visitor) const;
     virtual void SetForceRelayout(bool enable) = 0;
     virtual void AddChangedContainer(CXFA_Node* pContainer) = 0;
 
     void SetDocument(CXFA_Document* pDocument) { m_pDocument = pDocument; }
-    CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
+    CXFA_Document* GetDocument() const { return m_pDocument; }
 
    private:
-    UnownedPtr<CXFA_Document> m_pDocument;
+    cppgc::Member<CXFA_Document> m_pDocument;
   };
 
-  CXFA_Document(CXFA_FFNotify* notify,
-                std::unique_ptr<LayoutProcessorIface> pLayout);
-  ~CXFA_Document() override;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+  ~CXFA_Document();
+
+  void Trace(cppgc::Visitor* visitor) const;
 
   bool HasScriptContext() const { return !!m_pScriptContext; }
   CFXJSE_Engine* InitScriptContext(CJS_Runtime* fxjs_runtime);
@@ -81,6 +90,7 @@
   CFXJSE_Engine* GetScriptContext() const;
 
   CXFA_FFNotify* GetNotify() const { return notify_.Get(); }
+  CXFA_NodeOwner* GetNodeOwner() { return node_owner_; }
   cppgc::Heap* GetHeap() const;
   CXFA_LocaleMgr* GetLocaleMgr();
   CXFA_Object* GetXFAObject(XFA_HashCode wsNodeNameHash);
@@ -89,9 +99,8 @@
       const std::vector<UnownedPtr<CXFA_Object>>& arrayNodes) const;
 
   LayoutProcessorIface* GetLayoutProcessor() const {
-    return m_pLayoutProcessor.get();
+    return m_pLayoutProcessor;
   }
-
   CXFA_Node* GetRoot() const { return m_pRootNode; }
   void SetRoot(CXFA_Node* pNewRoot) { m_pRootNode = pNewRoot; }
 
@@ -128,18 +137,24 @@
   std::vector<CXFA_Node*> m_pPendingPageSet;
 
  private:
-  UnownedPtr<CXFA_FFNotify> const notify_;
-  CXFA_Node* m_pRootNode = nullptr;
-  std::map<uint32_t, CXFA_Node*> m_rgGlobalBinding;
+  CXFA_Document(CXFA_FFNotify* notify,
+                cppgc::Heap* heap,
+                LayoutProcessorIface* pLayout);
+
+  UnownedPtr<cppgc::Heap> heap_;
+  cppgc::Member<CXFA_FFNotify> const notify_;
+  cppgc::Member<CXFA_NodeOwner> const node_owner_;
+  cppgc::Member<CXFA_Node> m_pRootNode;
+  std::map<uint32_t, cppgc::Member<CXFA_Node>> m_rgGlobalBinding;
   std::unique_ptr<CFXJSE_Engine> m_pScriptContext;
-  std::unique_ptr<LayoutProcessorIface> m_pLayoutProcessor;
+  cppgc::Member<LayoutProcessorIface> m_pLayoutProcessor;
   std::unique_ptr<CXFA_LocaleMgr> m_pLocaleMgr;
-  std::unique_ptr<CScript_DataWindow> m_pScriptDataWindow;
-  std::unique_ptr<CScript_EventPseudoModel> m_pScriptEvent;
-  std::unique_ptr<CScript_HostPseudoModel> m_pScriptHost;
-  std::unique_ptr<CScript_LogPseudoModel> m_pScriptLog;
-  std::unique_ptr<CScript_LayoutPseudoModel> m_pScriptLayout;
-  std::unique_ptr<CScript_SignaturePseudoModel> m_pScriptSignature;
+  cppgc::Member<CScript_DataWindow> m_pScriptDataWindow;
+  cppgc::Member<CScript_EventPseudoModel> m_pScriptEvent;
+  cppgc::Member<CScript_HostPseudoModel> m_pScriptHost;
+  cppgc::Member<CScript_LogPseudoModel> m_pScriptLog;
+  cppgc::Member<CScript_LayoutPseudoModel> m_pScriptLayout;
+  cppgc::Member<CScript_SignaturePseudoModel> m_pScriptSignature;
   XFA_VERSION m_eCurVersionMode = XFA_VERSION_DEFAULT;
   Optional<bool> m_Interactive;
   bool m_bStrictScoping = false;
diff --git a/xfa/fxfa/parser/cxfa_document_builder.h b/xfa/fxfa/parser/cxfa_document_builder.h
index da721d8..bf76295 100644
--- a/xfa/fxfa/parser/cxfa_document_builder.h
+++ b/xfa/fxfa/parser/cxfa_document_builder.h
@@ -7,11 +7,11 @@
 #ifndef XFA_FXFA_PARSER_CXFA_DOCUMENT_BUILDER_H_
 #define XFA_FXFA_PARSER_CXFA_DOCUMENT_BUILDER_H_
 
-#include <memory>
 #include <utility>
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
 class CFX_XMLDocument;
@@ -64,9 +64,9 @@
                         CFX_XMLInstruction* pXMLInstruction,
                         XFA_PacketType ePacketID);
 
-  UnownedPtr<CXFA_Document> node_factory_;
+  cppgc::Persistent<CXFA_Document> node_factory_;
+  cppgc::Persistent<CXFA_Node> root_node_;
   UnownedPtr<CFX_XMLDocument> xml_doc_;
-  UnownedPtr<CXFA_Node> root_node_;  // All nodes owned by CXFA_NodeOwner.
   size_t execute_recursion_depth_ = 0;
 };
 
diff --git a/xfa/fxfa/parser/cxfa_document_builder_unittest.cpp b/xfa/fxfa/parser/cxfa_document_builder_unittest.cpp
index e105ca1..63283a1 100644
--- a/xfa/fxfa/parser/cxfa_document_builder_unittest.cpp
+++ b/xfa/fxfa/parser/cxfa_document_builder_unittest.cpp
@@ -7,17 +7,28 @@
 #include "core/fxcrt/cfx_readonlymemorystream.h"
 #include "core/fxcrt/xml/cfx_xmldocument.h"
 #include "core/fxcrt/xml/cfx_xmlparser.h"
+#include "testing/fxgc_unittest.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 
-class CXFA_DocumentBuilderTest : public testing::Test {
+class CXFA_DocumentBuilderTest : public FXGCUnitTest {
  public:
   void SetUp() override {
-    doc_ = std::make_unique<CXFA_Document>(nullptr, nullptr);
-    builder_ = std::make_unique<CXFA_DocumentBuilder>(doc_.get());
+    FXGCUnitTest::SetUp();
+    doc_ = cppgc::MakeGarbageCollected<CXFA_Document>(
+        heap()->GetAllocationHandle(), nullptr, heap(), nullptr);
+    builder_ = std::make_unique<CXFA_DocumentBuilder>(doc_);
   }
 
-  CXFA_Document* GetDoc() const { return doc_.get(); }
+  void TearDown() override {
+    builder_.reset();
+    doc_ = nullptr;
+    FXGCUnitTest::TearDown();
+  }
+
+  CXFA_Document* GetDoc() const { return doc_; }
 
   CXFA_Node* ParseAndBuild(const RetainPtr<CFX_ReadOnlyMemoryStream>& stream) {
     xml_ = CFX_XMLParser(stream).Parse();
@@ -30,8 +41,8 @@
 
  private:
   std::unique_ptr<CFX_XMLDocument> xml_;
-  std::unique_ptr<CXFA_Document> doc_;
   std::unique_ptr<CXFA_DocumentBuilder> builder_;
+  cppgc::Persistent<CXFA_Document> doc_;
 };
 
 TEST_F(CXFA_DocumentBuilderTest, EmptyInput) {
diff --git a/xfa/fxfa/parser/cxfa_documentassembly.h b/xfa/fxfa/parser/cxfa_documentassembly.h
index 92cde65..e0c5767 100644
--- a/xfa/fxfa/parser/cxfa_documentassembly.h
+++ b/xfa/fxfa/parser/cxfa_documentassembly.h
@@ -11,8 +11,11 @@
 
 class CXFA_DocumentAssembly final : public CXFA_Node {
  public:
-  CXFA_DocumentAssembly(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DocumentAssembly() override;
+
+ private:
+  CXFA_DocumentAssembly(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DOCUMENTASSEMBLY_H_
diff --git a/xfa/fxfa/parser/cxfa_draw.h b/xfa/fxfa/parser/cxfa_draw.h
index c1b9006..1709d23 100644
--- a/xfa/fxfa/parser/cxfa_draw.h
+++ b/xfa/fxfa/parser/cxfa_draw.h
@@ -11,8 +11,11 @@
 
 class CXFA_Draw final : public CXFA_Node {
  public:
-  CXFA_Draw(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Draw() override;
+
+ private:
+  CXFA_Draw(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DRAW_H_
diff --git a/xfa/fxfa/parser/cxfa_driver.h b/xfa/fxfa/parser/cxfa_driver.h
index f58e153..fe94de6 100644
--- a/xfa/fxfa/parser/cxfa_driver.h
+++ b/xfa/fxfa/parser/cxfa_driver.h
@@ -11,8 +11,11 @@
 
 class CXFA_Driver final : public CXFA_Node {
  public:
-  CXFA_Driver(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Driver() override;
+
+ private:
+  CXFA_Driver(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DRIVER_H_
diff --git a/xfa/fxfa/parser/cxfa_dsigdata.h b/xfa/fxfa/parser/cxfa_dsigdata.h
index 06e691c..716d780 100644
--- a/xfa/fxfa/parser/cxfa_dsigdata.h
+++ b/xfa/fxfa/parser/cxfa_dsigdata.h
@@ -11,8 +11,11 @@
 
 class CXFA_DSigData final : public CXFA_Node {
  public:
-  CXFA_DSigData(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DSigData() override;
+
+ private:
+  CXFA_DSigData(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DSIGDATA_H_
diff --git a/xfa/fxfa/parser/cxfa_duplexoption.h b/xfa/fxfa/parser/cxfa_duplexoption.h
index 5bf8e50..58e4cfd 100644
--- a/xfa/fxfa/parser/cxfa_duplexoption.h
+++ b/xfa/fxfa/parser/cxfa_duplexoption.h
@@ -11,8 +11,11 @@
 
 class CXFA_DuplexOption final : public CXFA_Node {
  public:
-  CXFA_DuplexOption(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DuplexOption() override;
+
+ private:
+  CXFA_DuplexOption(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DUPLEXOPTION_H_
diff --git a/xfa/fxfa/parser/cxfa_dynamicrender.h b/xfa/fxfa/parser/cxfa_dynamicrender.h
index 78b75a7..fa14abd 100644
--- a/xfa/fxfa/parser/cxfa_dynamicrender.h
+++ b/xfa/fxfa/parser/cxfa_dynamicrender.h
@@ -11,8 +11,11 @@
 
 class CXFA_DynamicRender final : public CXFA_Node {
  public:
-  CXFA_DynamicRender(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_DynamicRender() override;
+
+ private:
+  CXFA_DynamicRender(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_DYNAMICRENDER_H_
diff --git a/xfa/fxfa/parser/cxfa_edge.h b/xfa/fxfa/parser/cxfa_edge.h
index 79c7f14..1350e9b 100644
--- a/xfa/fxfa/parser/cxfa_edge.h
+++ b/xfa/fxfa/parser/cxfa_edge.h
@@ -13,8 +13,11 @@
  public:
   static constexpr FX_ARGB kDefaultColor = 0xFF000000;
 
-  CXFA_Edge(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Edge() override;
+
+ private:
+  CXFA_Edge(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EDGE_H_
diff --git a/xfa/fxfa/parser/cxfa_effectiveinputpolicy.h b/xfa/fxfa/parser/cxfa_effectiveinputpolicy.h
index 4f4fb8e..76e71aa 100644
--- a/xfa/fxfa/parser/cxfa_effectiveinputpolicy.h
+++ b/xfa/fxfa/parser/cxfa_effectiveinputpolicy.h
@@ -11,8 +11,11 @@
 
 class CXFA_EffectiveInputPolicy final : public CXFA_Node {
  public:
-  CXFA_EffectiveInputPolicy(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EffectiveInputPolicy() override;
+
+ private:
+  CXFA_EffectiveInputPolicy(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EFFECTIVEINPUTPOLICY_H_
diff --git a/xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h b/xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h
index 9b15a47..14bb7a5 100644
--- a/xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h
+++ b/xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h
@@ -11,8 +11,11 @@
 
 class CXFA_EffectiveOutputPolicy final : public CXFA_Node {
  public:
-  CXFA_EffectiveOutputPolicy(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EffectiveOutputPolicy() override;
+
+ private:
+  CXFA_EffectiveOutputPolicy(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EFFECTIVEOUTPUTPOLICY_H_
diff --git a/xfa/fxfa/parser/cxfa_embed.h b/xfa/fxfa/parser/cxfa_embed.h
index 8772b30..9a46fd7 100644
--- a/xfa/fxfa/parser/cxfa_embed.h
+++ b/xfa/fxfa/parser/cxfa_embed.h
@@ -11,8 +11,11 @@
 
 class CXFA_Embed final : public CXFA_Node {
  public:
-  CXFA_Embed(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Embed() override;
+
+ private:
+  CXFA_Embed(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EMBED_H_
diff --git a/xfa/fxfa/parser/cxfa_encoding.h b/xfa/fxfa/parser/cxfa_encoding.h
index b98ea21..50a1ba3 100644
--- a/xfa/fxfa/parser/cxfa_encoding.h
+++ b/xfa/fxfa/parser/cxfa_encoding.h
@@ -11,8 +11,11 @@
 
 class CXFA_Encoding final : public CXFA_Node {
  public:
-  CXFA_Encoding(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Encoding() override;
+
+ private:
+  CXFA_Encoding(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCODING_H_
diff --git a/xfa/fxfa/parser/cxfa_encodings.h b/xfa/fxfa/parser/cxfa_encodings.h
index 3e8de09..6b4b582 100644
--- a/xfa/fxfa/parser/cxfa_encodings.h
+++ b/xfa/fxfa/parser/cxfa_encodings.h
@@ -11,8 +11,11 @@
 
 class CXFA_Encodings final : public CXFA_Node {
  public:
-  CXFA_Encodings(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Encodings() override;
+
+ private:
+  CXFA_Encodings(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCODINGS_H_
diff --git a/xfa/fxfa/parser/cxfa_encrypt.h b/xfa/fxfa/parser/cxfa_encrypt.h
index afb74b4..e5bd2c3 100644
--- a/xfa/fxfa/parser/cxfa_encrypt.h
+++ b/xfa/fxfa/parser/cxfa_encrypt.h
@@ -11,8 +11,11 @@
 
 class CXFA_Encrypt final : public CXFA_Node {
  public:
-  CXFA_Encrypt(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Encrypt() override;
+
+ private:
+  CXFA_Encrypt(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCRYPT_H_
diff --git a/xfa/fxfa/parser/cxfa_encryption.h b/xfa/fxfa/parser/cxfa_encryption.h
index 1bcf48f..96c4c83 100644
--- a/xfa/fxfa/parser/cxfa_encryption.h
+++ b/xfa/fxfa/parser/cxfa_encryption.h
@@ -11,8 +11,11 @@
 
 class CXFA_Encryption final : public CXFA_Node {
  public:
-  CXFA_Encryption(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Encryption() override;
+
+ private:
+  CXFA_Encryption(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCRYPTION_H_
diff --git a/xfa/fxfa/parser/cxfa_encryptionlevel.h b/xfa/fxfa/parser/cxfa_encryptionlevel.h
index faf300b..4e08e88 100644
--- a/xfa/fxfa/parser/cxfa_encryptionlevel.h
+++ b/xfa/fxfa/parser/cxfa_encryptionlevel.h
@@ -11,8 +11,11 @@
 
 class CXFA_EncryptionLevel final : public CXFA_Node {
  public:
-  CXFA_EncryptionLevel(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EncryptionLevel() override;
+
+ private:
+  CXFA_EncryptionLevel(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCRYPTIONLEVEL_H_
diff --git a/xfa/fxfa/parser/cxfa_encryptionmethod.h b/xfa/fxfa/parser/cxfa_encryptionmethod.h
index cae708f..bb332c6 100644
--- a/xfa/fxfa/parser/cxfa_encryptionmethod.h
+++ b/xfa/fxfa/parser/cxfa_encryptionmethod.h
@@ -11,8 +11,11 @@
 
 class CXFA_EncryptionMethod final : public CXFA_Node {
  public:
-  CXFA_EncryptionMethod(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EncryptionMethod() override;
+
+ private:
+  CXFA_EncryptionMethod(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCRYPTIONMETHOD_H_
diff --git a/xfa/fxfa/parser/cxfa_encryptionmethods.h b/xfa/fxfa/parser/cxfa_encryptionmethods.h
index 825ee9f..e756c55 100644
--- a/xfa/fxfa/parser/cxfa_encryptionmethods.h
+++ b/xfa/fxfa/parser/cxfa_encryptionmethods.h
@@ -11,8 +11,11 @@
 
 class CXFA_EncryptionMethods final : public CXFA_Node {
  public:
-  CXFA_EncryptionMethods(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EncryptionMethods() override;
+
+ private:
+  CXFA_EncryptionMethods(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENCRYPTIONMETHODS_H_
diff --git a/xfa/fxfa/parser/cxfa_enforce.h b/xfa/fxfa/parser/cxfa_enforce.h
index ec7d745..680043b 100644
--- a/xfa/fxfa/parser/cxfa_enforce.h
+++ b/xfa/fxfa/parser/cxfa_enforce.h
@@ -11,8 +11,11 @@
 
 class CXFA_Enforce final : public CXFA_Node {
  public:
-  CXFA_Enforce(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Enforce() override;
+
+ private:
+  CXFA_Enforce(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ENFORCE_H_
diff --git a/xfa/fxfa/parser/cxfa_equate.h b/xfa/fxfa/parser/cxfa_equate.h
index fc1f8d6..d14a988 100644
--- a/xfa/fxfa/parser/cxfa_equate.h
+++ b/xfa/fxfa/parser/cxfa_equate.h
@@ -11,8 +11,11 @@
 
 class CXFA_Equate final : public CXFA_Node {
  public:
-  CXFA_Equate(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Equate() override;
+
+ private:
+  CXFA_Equate(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EQUATE_H_
diff --git a/xfa/fxfa/parser/cxfa_equaterange.h b/xfa/fxfa/parser/cxfa_equaterange.h
index 56f05e1..7be04bf 100644
--- a/xfa/fxfa/parser/cxfa_equaterange.h
+++ b/xfa/fxfa/parser/cxfa_equaterange.h
@@ -11,8 +11,11 @@
 
 class CXFA_EquateRange final : public CXFA_Node {
  public:
-  CXFA_EquateRange(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EquateRange() override;
+
+ private:
+  CXFA_EquateRange(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EQUATERANGE_H_
diff --git a/xfa/fxfa/parser/cxfa_era.h b/xfa/fxfa/parser/cxfa_era.h
index e0ecdf7..85b7339 100644
--- a/xfa/fxfa/parser/cxfa_era.h
+++ b/xfa/fxfa/parser/cxfa_era.h
@@ -11,8 +11,11 @@
 
 class CXFA_Era final : public CXFA_Node {
  public:
-  CXFA_Era(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Era() override;
+
+ private:
+  CXFA_Era(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ERA_H_
diff --git a/xfa/fxfa/parser/cxfa_eranames.h b/xfa/fxfa/parser/cxfa_eranames.h
index 468b658..ca4e35f 100644
--- a/xfa/fxfa/parser/cxfa_eranames.h
+++ b/xfa/fxfa/parser/cxfa_eranames.h
@@ -11,8 +11,11 @@
 
 class CXFA_EraNames final : public CXFA_Node {
  public:
-  CXFA_EraNames(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_EraNames() override;
+
+ private:
+  CXFA_EraNames(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ERANAMES_H_
diff --git a/xfa/fxfa/parser/cxfa_event.h b/xfa/fxfa/parser/cxfa_event.h
index 73da7c2..07180a5 100644
--- a/xfa/fxfa/parser/cxfa_event.h
+++ b/xfa/fxfa/parser/cxfa_event.h
@@ -14,7 +14,7 @@
 
 class CXFA_Event final : public CXFA_Node {
  public:
-  CXFA_Event(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Event() override;
 
   XFA_AttributeValue GetActivity();
@@ -26,6 +26,9 @@
 #endif  // PDF_XFA_ELEMENT_SUBMIT_ENABLED
 
   WideString GetRef();
+
+ private:
+  CXFA_Event(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EVENT_H_
diff --git a/xfa/fxfa/parser/cxfa_exclgroup.h b/xfa/fxfa/parser/cxfa_exclgroup.h
index 390bb4a..b10395d 100644
--- a/xfa/fxfa/parser/cxfa_exclgroup.h
+++ b/xfa/fxfa/parser/cxfa_exclgroup.h
@@ -11,8 +11,11 @@
 
 class CXFA_ExclGroup final : public CXFA_Node {
  public:
-  CXFA_ExclGroup(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ExclGroup() override;
+
+ private:
+  CXFA_ExclGroup(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXCLGROUP_H_
diff --git a/xfa/fxfa/parser/cxfa_exclude.h b/xfa/fxfa/parser/cxfa_exclude.h
index 71f08fd..e7ab948 100644
--- a/xfa/fxfa/parser/cxfa_exclude.h
+++ b/xfa/fxfa/parser/cxfa_exclude.h
@@ -11,8 +11,11 @@
 
 class CXFA_Exclude final : public CXFA_Node {
  public:
-  CXFA_Exclude(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Exclude() override;
+
+ private:
+  CXFA_Exclude(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXCLUDE_H_
diff --git a/xfa/fxfa/parser/cxfa_excludens.h b/xfa/fxfa/parser/cxfa_excludens.h
index 9ce2e69..c90b2fa 100644
--- a/xfa/fxfa/parser/cxfa_excludens.h
+++ b/xfa/fxfa/parser/cxfa_excludens.h
@@ -11,8 +11,11 @@
 
 class CXFA_ExcludeNS final : public CXFA_Node {
  public:
-  CXFA_ExcludeNS(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ExcludeNS() override;
+
+ private:
+  CXFA_ExcludeNS(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXCLUDENS_H_
diff --git a/xfa/fxfa/parser/cxfa_exdata.h b/xfa/fxfa/parser/cxfa_exdata.h
index 8adf028..27c5fb2 100644
--- a/xfa/fxfa/parser/cxfa_exdata.h
+++ b/xfa/fxfa/parser/cxfa_exdata.h
@@ -11,10 +11,13 @@
 
 class CXFA_ExData final : public CXFA_Node {
  public:
-  CXFA_ExData(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ExData() override;
 
   void SetContentType(const WideString& wsContentType);
+
+ private:
+  CXFA_ExData(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXDATA_H_
diff --git a/xfa/fxfa/parser/cxfa_execute.h b/xfa/fxfa/parser/cxfa_execute.h
index 63fd18b..4b7613b 100644
--- a/xfa/fxfa/parser/cxfa_execute.h
+++ b/xfa/fxfa/parser/cxfa_execute.h
@@ -11,8 +11,11 @@
 
 class CXFA_Execute final : public CXFA_Node {
  public:
-  CXFA_Execute(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Execute() override;
+
+ private:
+  CXFA_Execute(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXECUTE_H_
diff --git a/xfa/fxfa/parser/cxfa_exobject.h b/xfa/fxfa/parser/cxfa_exobject.h
index 79ffdb9..0ee622c 100644
--- a/xfa/fxfa/parser/cxfa_exobject.h
+++ b/xfa/fxfa/parser/cxfa_exobject.h
@@ -11,8 +11,11 @@
 
 class CXFA_ExObject final : public CXFA_Node {
  public:
-  CXFA_ExObject(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ExObject() override;
+
+ private:
+  CXFA_ExObject(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXOBJECT_H_
diff --git a/xfa/fxfa/parser/cxfa_extras.h b/xfa/fxfa/parser/cxfa_extras.h
index 82108d0..bac50a7 100644
--- a/xfa/fxfa/parser/cxfa_extras.h
+++ b/xfa/fxfa/parser/cxfa_extras.h
@@ -11,8 +11,11 @@
 
 class CXFA_Extras final : public CXFA_Node {
  public:
-  CXFA_Extras(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Extras() override;
+
+ private:
+  CXFA_Extras(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_EXTRAS_H_
diff --git a/xfa/fxfa/parser/cxfa_field.h b/xfa/fxfa/parser/cxfa_field.h
index e29cdd7..6bdfeba 100644
--- a/xfa/fxfa/parser/cxfa_field.h
+++ b/xfa/fxfa/parser/cxfa_field.h
@@ -11,8 +11,11 @@
 
 class CXFA_Field final : public CXFA_Node {
  public:
-  CXFA_Field(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Field() override;
+
+ private:
+  CXFA_Field(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FIELD_H_
diff --git a/xfa/fxfa/parser/cxfa_fill.h b/xfa/fxfa/parser/cxfa_fill.h
index 05fede9..8947aec 100644
--- a/xfa/fxfa/parser/cxfa_fill.h
+++ b/xfa/fxfa/parser/cxfa_fill.h
@@ -20,7 +20,7 @@
 
 class CXFA_Fill final : public CXFA_Node {
  public:
-  CXFA_Fill(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Fill() override;
 
   bool IsVisible();
@@ -34,6 +34,8 @@
             const CFX_Matrix& matrix);
 
  private:
+  CXFA_Fill(CXFA_Document* doc, XFA_PacketType packet);
+
   XFA_Element GetType() const;
 
   void DrawStipple(CXFA_Graphics* pGS,
diff --git a/xfa/fxfa/parser/cxfa_filter.h b/xfa/fxfa/parser/cxfa_filter.h
index 033d97c..07a65ed 100644
--- a/xfa/fxfa/parser/cxfa_filter.h
+++ b/xfa/fxfa/parser/cxfa_filter.h
@@ -11,8 +11,11 @@
 
 class CXFA_Filter final : public CXFA_Node {
  public:
-  CXFA_Filter(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Filter() override;
+
+ private:
+  CXFA_Filter(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FILTER_H_
diff --git a/xfa/fxfa/parser/cxfa_fliplabel.h b/xfa/fxfa/parser/cxfa_fliplabel.h
index e3f8165..02b6571 100644
--- a/xfa/fxfa/parser/cxfa_fliplabel.h
+++ b/xfa/fxfa/parser/cxfa_fliplabel.h
@@ -11,8 +11,11 @@
 
 class CXFA_FlipLabel final : public CXFA_Node {
  public:
-  CXFA_FlipLabel(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FlipLabel() override;
+
+ private:
+  CXFA_FlipLabel(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FLIPLABEL_H_
diff --git a/xfa/fxfa/parser/cxfa_float.h b/xfa/fxfa/parser/cxfa_float.h
index a3fc1ae..262ab18 100644
--- a/xfa/fxfa/parser/cxfa_float.h
+++ b/xfa/fxfa/parser/cxfa_float.h
@@ -11,8 +11,11 @@
 
 class CXFA_Float final : public CXFA_Node {
  public:
-  CXFA_Float(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Float() override;
+
+ private:
+  CXFA_Float(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FLOAT_H_
diff --git a/xfa/fxfa/parser/cxfa_font.h b/xfa/fxfa/parser/cxfa_font.h
index e292ed5..97389dd 100644
--- a/xfa/fxfa/parser/cxfa_font.h
+++ b/xfa/fxfa/parser/cxfa_font.h
@@ -12,7 +12,7 @@
 
 class CXFA_Font final : public CXFA_Node {
  public:
-  CXFA_Font(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Font() override;
 
   float GetBaselineShift() const;
@@ -30,6 +30,9 @@
 
   FX_ARGB GetColor();
   void SetColor(FX_ARGB color);
+
+ private:
+  CXFA_Font(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FONT_H_
diff --git a/xfa/fxfa/parser/cxfa_fontinfo.h b/xfa/fxfa/parser/cxfa_fontinfo.h
index b798c55..1a48364 100644
--- a/xfa/fxfa/parser/cxfa_fontinfo.h
+++ b/xfa/fxfa/parser/cxfa_fontinfo.h
@@ -11,8 +11,11 @@
 
 class CXFA_FontInfo final : public CXFA_Node {
  public:
-  CXFA_FontInfo(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FontInfo() override;
+
+ private:
+  CXFA_FontInfo(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FONTINFO_H_
diff --git a/xfa/fxfa/parser/cxfa_form.h b/xfa/fxfa/parser/cxfa_form.h
index a0e2f32..79e3440 100644
--- a/xfa/fxfa/parser/cxfa_form.h
+++ b/xfa/fxfa/parser/cxfa_form.h
@@ -11,8 +11,11 @@
 
 class CXFA_Form final : public CXFA_Node {
  public:
-  CXFA_Form(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Form() override;
+
+ private:
+  CXFA_Form(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FORM_H_
diff --git a/xfa/fxfa/parser/cxfa_format.h b/xfa/fxfa/parser/cxfa_format.h
index 7e74a1c..887bf7a 100644
--- a/xfa/fxfa/parser/cxfa_format.h
+++ b/xfa/fxfa/parser/cxfa_format.h
@@ -11,8 +11,11 @@
 
 class CXFA_Format final : public CXFA_Node {
  public:
-  CXFA_Format(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Format() override;
+
+ private:
+  CXFA_Format(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FORMAT_H_
diff --git a/xfa/fxfa/parser/cxfa_formfieldfilling.h b/xfa/fxfa/parser/cxfa_formfieldfilling.h
index f9e7447..7847852 100644
--- a/xfa/fxfa/parser/cxfa_formfieldfilling.h
+++ b/xfa/fxfa/parser/cxfa_formfieldfilling.h
@@ -11,8 +11,11 @@
 
 class CXFA_FormFieldFilling final : public CXFA_Node {
  public:
-  CXFA_FormFieldFilling(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FormFieldFilling() override;
+
+ private:
+  CXFA_FormFieldFilling(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_FORMFIELDFILLING_H_
diff --git a/xfa/fxfa/parser/cxfa_groupparent.h b/xfa/fxfa/parser/cxfa_groupparent.h
index eb63a6a..a4c0a85 100644
--- a/xfa/fxfa/parser/cxfa_groupparent.h
+++ b/xfa/fxfa/parser/cxfa_groupparent.h
@@ -11,8 +11,11 @@
 
 class CXFA_GroupParent final : public CXFA_Node {
  public:
-  CXFA_GroupParent(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_GroupParent() override;
+
+ private:
+  CXFA_GroupParent(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_GROUPPARENT_H_
diff --git a/xfa/fxfa/parser/cxfa_handler.h b/xfa/fxfa/parser/cxfa_handler.h
index 1ab1c4d..962fa00 100644
--- a/xfa/fxfa/parser/cxfa_handler.h
+++ b/xfa/fxfa/parser/cxfa_handler.h
@@ -11,8 +11,11 @@
 
 class CXFA_Handler final : public CXFA_Node {
  public:
-  CXFA_Handler(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Handler() override;
+
+ private:
+  CXFA_Handler(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_HANDLER_H_
diff --git a/xfa/fxfa/parser/cxfa_hyphenation.h b/xfa/fxfa/parser/cxfa_hyphenation.h
index 77b49e9..7285b5b 100644
--- a/xfa/fxfa/parser/cxfa_hyphenation.h
+++ b/xfa/fxfa/parser/cxfa_hyphenation.h
@@ -11,8 +11,11 @@
 
 class CXFA_Hyphenation final : public CXFA_Node {
  public:
-  CXFA_Hyphenation(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Hyphenation() override;
+
+ private:
+  CXFA_Hyphenation(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_HYPHENATION_H_
diff --git a/xfa/fxfa/parser/cxfa_ifempty.h b/xfa/fxfa/parser/cxfa_ifempty.h
index 401faa7..e14cbcb 100644
--- a/xfa/fxfa/parser/cxfa_ifempty.h
+++ b/xfa/fxfa/parser/cxfa_ifempty.h
@@ -11,8 +11,11 @@
 
 class CXFA_IfEmpty final : public CXFA_Node {
  public:
-  CXFA_IfEmpty(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_IfEmpty() override;
+
+ private:
+  CXFA_IfEmpty(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_IFEMPTY_H_
diff --git a/xfa/fxfa/parser/cxfa_image.h b/xfa/fxfa/parser/cxfa_image.h
index 62bb93a..bf84c93 100644
--- a/xfa/fxfa/parser/cxfa_image.h
+++ b/xfa/fxfa/parser/cxfa_image.h
@@ -11,7 +11,7 @@
 
 class CXFA_Image final : public CXFA_Node {
  public:
-  CXFA_Image(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Image() override;
 
   XFA_AttributeValue GetAspect();
@@ -25,6 +25,9 @@
 
   WideString GetContentType();
   void SetContentType(const WideString& wsContentType);
+
+ private:
+  CXFA_Image(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_IMAGE_H_
diff --git a/xfa/fxfa/parser/cxfa_imageedit.h b/xfa/fxfa/parser/cxfa_imageedit.h
index 884c219..d8adbcc 100644
--- a/xfa/fxfa/parser/cxfa_imageedit.h
+++ b/xfa/fxfa/parser/cxfa_imageedit.h
@@ -11,11 +11,14 @@
 
 class CXFA_ImageEdit final : public CXFA_Node {
  public:
-  CXFA_ImageEdit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ImageEdit() override;
 
   XFA_Element GetValueNodeType() const override;
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_ImageEdit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_IMAGEEDIT_H_
diff --git a/xfa/fxfa/parser/cxfa_includexdpcontent.h b/xfa/fxfa/parser/cxfa_includexdpcontent.h
index 15c5bbe..7e7238c 100644
--- a/xfa/fxfa/parser/cxfa_includexdpcontent.h
+++ b/xfa/fxfa/parser/cxfa_includexdpcontent.h
@@ -11,8 +11,11 @@
 
 class CXFA_IncludeXDPContent final : public CXFA_Node {
  public:
-  CXFA_IncludeXDPContent(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_IncludeXDPContent() override;
+
+ private:
+  CXFA_IncludeXDPContent(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INCLUDEXDPCONTENT_H_
diff --git a/xfa/fxfa/parser/cxfa_incrementalload.h b/xfa/fxfa/parser/cxfa_incrementalload.h
index 253a2ae..260b3af 100644
--- a/xfa/fxfa/parser/cxfa_incrementalload.h
+++ b/xfa/fxfa/parser/cxfa_incrementalload.h
@@ -11,8 +11,11 @@
 
 class CXFA_IncrementalLoad final : public CXFA_Node {
  public:
-  CXFA_IncrementalLoad(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_IncrementalLoad() override;
+
+ private:
+  CXFA_IncrementalLoad(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INCREMENTALLOAD_H_
diff --git a/xfa/fxfa/parser/cxfa_incrementalmerge.h b/xfa/fxfa/parser/cxfa_incrementalmerge.h
index 4ec65af..bfc0689 100644
--- a/xfa/fxfa/parser/cxfa_incrementalmerge.h
+++ b/xfa/fxfa/parser/cxfa_incrementalmerge.h
@@ -11,8 +11,11 @@
 
 class CXFA_IncrementalMerge final : public CXFA_Node {
  public:
-  CXFA_IncrementalMerge(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_IncrementalMerge() override;
+
+ private:
+  CXFA_IncrementalMerge(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INCREMENTALMERGE_H_
diff --git a/xfa/fxfa/parser/cxfa_insert.h b/xfa/fxfa/parser/cxfa_insert.h
index e157a82..97fbf85 100644
--- a/xfa/fxfa/parser/cxfa_insert.h
+++ b/xfa/fxfa/parser/cxfa_insert.h
@@ -11,8 +11,11 @@
 
 class CXFA_Insert final : public CXFA_Node {
  public:
-  CXFA_Insert(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Insert() override;
+
+ private:
+  CXFA_Insert(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INSERT_H_
diff --git a/xfa/fxfa/parser/cxfa_instancemanager.h b/xfa/fxfa/parser/cxfa_instancemanager.h
index 3ace0e9..d7de269 100644
--- a/xfa/fxfa/parser/cxfa_instancemanager.h
+++ b/xfa/fxfa/parser/cxfa_instancemanager.h
@@ -11,8 +11,11 @@
 
 class CXFA_InstanceManager final : public CXFA_Node {
  public:
-  CXFA_InstanceManager(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_InstanceManager() override;
+
+ private:
+  CXFA_InstanceManager(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INSTANCEMANAGER_H_
diff --git a/xfa/fxfa/parser/cxfa_integer.h b/xfa/fxfa/parser/cxfa_integer.h
index ac94133..7cbb2b7 100644
--- a/xfa/fxfa/parser/cxfa_integer.h
+++ b/xfa/fxfa/parser/cxfa_integer.h
@@ -11,8 +11,11 @@
 
 class CXFA_Integer final : public CXFA_Node {
  public:
-  CXFA_Integer(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Integer() override;
+
+ private:
+  CXFA_Integer(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INTEGER_H_
diff --git a/xfa/fxfa/parser/cxfa_interactive.h b/xfa/fxfa/parser/cxfa_interactive.h
index 12db0bf..964f54a 100644
--- a/xfa/fxfa/parser/cxfa_interactive.h
+++ b/xfa/fxfa/parser/cxfa_interactive.h
@@ -11,8 +11,11 @@
 
 class CXFA_Interactive final : public CXFA_Node {
  public:
-  CXFA_Interactive(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Interactive() override;
+
+ private:
+  CXFA_Interactive(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_INTERACTIVE_H_
diff --git a/xfa/fxfa/parser/cxfa_issuers.h b/xfa/fxfa/parser/cxfa_issuers.h
index 11ba8b4..541918d 100644
--- a/xfa/fxfa/parser/cxfa_issuers.h
+++ b/xfa/fxfa/parser/cxfa_issuers.h
@@ -11,8 +11,11 @@
 
 class CXFA_Issuers final : public CXFA_Node {
  public:
-  CXFA_Issuers(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Issuers() override;
+
+ private:
+  CXFA_Issuers(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ISSUERS_H_
diff --git a/xfa/fxfa/parser/cxfa_items.h b/xfa/fxfa/parser/cxfa_items.h
index 609b028..8e03382 100644
--- a/xfa/fxfa/parser/cxfa_items.h
+++ b/xfa/fxfa/parser/cxfa_items.h
@@ -11,8 +11,11 @@
 
 class CXFA_Items final : public CXFA_Node {
  public:
-  CXFA_Items(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Items() override;
+
+ private:
+  CXFA_Items(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ITEMS_H_
diff --git a/xfa/fxfa/parser/cxfa_jog.h b/xfa/fxfa/parser/cxfa_jog.h
index a40a488..0fd2da3 100644
--- a/xfa/fxfa/parser/cxfa_jog.h
+++ b/xfa/fxfa/parser/cxfa_jog.h
@@ -11,8 +11,11 @@
 
 class CXFA_Jog final : public CXFA_Node {
  public:
-  CXFA_Jog(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Jog() override;
+
+ private:
+  CXFA_Jog(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_JOG_H_
diff --git a/xfa/fxfa/parser/cxfa_keep.h b/xfa/fxfa/parser/cxfa_keep.h
index 0d4a2e0..9139dfa 100644
--- a/xfa/fxfa/parser/cxfa_keep.h
+++ b/xfa/fxfa/parser/cxfa_keep.h
@@ -11,8 +11,11 @@
 
 class CXFA_Keep final : public CXFA_Node {
  public:
-  CXFA_Keep(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Keep() override;
+
+ private:
+  CXFA_Keep(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_KEEP_H_
diff --git a/xfa/fxfa/parser/cxfa_keyusage.h b/xfa/fxfa/parser/cxfa_keyusage.h
index 3409e3f..78dcc3d 100644
--- a/xfa/fxfa/parser/cxfa_keyusage.h
+++ b/xfa/fxfa/parser/cxfa_keyusage.h
@@ -11,8 +11,11 @@
 
 class CXFA_KeyUsage final : public CXFA_Node {
  public:
-  CXFA_KeyUsage(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_KeyUsage() override;
+
+ private:
+  CXFA_KeyUsage(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_KEYUSAGE_H_
diff --git a/xfa/fxfa/parser/cxfa_labelprinter.h b/xfa/fxfa/parser/cxfa_labelprinter.h
index 74a5e82..d90ad6b 100644
--- a/xfa/fxfa/parser/cxfa_labelprinter.h
+++ b/xfa/fxfa/parser/cxfa_labelprinter.h
@@ -11,8 +11,11 @@
 
 class CXFA_LabelPrinter final : public CXFA_Node {
  public:
-  CXFA_LabelPrinter(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_LabelPrinter() override;
+
+ private:
+  CXFA_LabelPrinter(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LABELPRINTER_H_
diff --git a/xfa/fxfa/parser/cxfa_layout.h b/xfa/fxfa/parser/cxfa_layout.h
index ad25efa..862b0c3 100644
--- a/xfa/fxfa/parser/cxfa_layout.h
+++ b/xfa/fxfa/parser/cxfa_layout.h
@@ -11,8 +11,11 @@
 
 class CXFA_Layout final : public CXFA_Node {
  public:
-  CXFA_Layout(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Layout() override;
+
+ private:
+  CXFA_Layout(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LAYOUT_H_
diff --git a/xfa/fxfa/parser/cxfa_level.h b/xfa/fxfa/parser/cxfa_level.h
index 8cc03dc..d563c9b 100644
--- a/xfa/fxfa/parser/cxfa_level.h
+++ b/xfa/fxfa/parser/cxfa_level.h
@@ -11,8 +11,11 @@
 
 class CXFA_Level final : public CXFA_Node {
  public:
-  CXFA_Level(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Level() override;
+
+ private:
+  CXFA_Level(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LEVEL_H_
diff --git a/xfa/fxfa/parser/cxfa_line.h b/xfa/fxfa/parser/cxfa_line.h
index 53584fa..9c63c95 100644
--- a/xfa/fxfa/parser/cxfa_line.h
+++ b/xfa/fxfa/parser/cxfa_line.h
@@ -13,12 +13,15 @@
 
 class CXFA_Line final : public CXFA_Node {
  public:
-  CXFA_Line(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Line() override;
 
   XFA_AttributeValue GetHand();
   bool GetSlope();
   CXFA_Edge* GetEdgeIfExists();
+
+ private:
+  CXFA_Line(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LINE_H_
diff --git a/xfa/fxfa/parser/cxfa_linear.h b/xfa/fxfa/parser/cxfa_linear.h
index 0fa5e1a..e7625a1 100644
--- a/xfa/fxfa/parser/cxfa_linear.h
+++ b/xfa/fxfa/parser/cxfa_linear.h
@@ -19,7 +19,7 @@
   static constexpr XFA_AttributeValue kDefaultType =
       XFA_AttributeValue::ToRight;
 
-  CXFA_Linear(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Linear() override;
 
   void Draw(CXFA_Graphics* pGS,
@@ -29,6 +29,8 @@
             const CFX_Matrix& matrix);
 
  private:
+  CXFA_Linear(CXFA_Document* doc, XFA_PacketType packet);
+
   XFA_AttributeValue GetType();
   CXFA_Color* GetColorIfExists();
 };
diff --git a/xfa/fxfa/parser/cxfa_linearized.h b/xfa/fxfa/parser/cxfa_linearized.h
index d2fe2d7..ddcd8f7 100644
--- a/xfa/fxfa/parser/cxfa_linearized.h
+++ b/xfa/fxfa/parser/cxfa_linearized.h
@@ -11,8 +11,11 @@
 
 class CXFA_Linearized final : public CXFA_Node {
  public:
-  CXFA_Linearized(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Linearized() override;
+
+ private:
+  CXFA_Linearized(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LINEARIZED_H_
diff --git a/xfa/fxfa/parser/cxfa_list.h b/xfa/fxfa/parser/cxfa_list.h
index c114801..9317a34 100644
--- a/xfa/fxfa/parser/cxfa_list.h
+++ b/xfa/fxfa/parser/cxfa_list.h
@@ -9,12 +9,16 @@
 
 #include <memory>
 
+#include "fxjs/gc/heap.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
 
+class CJX_Object;
 class CXFA_Document;
+class CXFA_Node;
 
 class CXFA_List : public CXFA_Object {
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_List() override;
 
   virtual size_t GetLength() = 0;
diff --git a/xfa/fxfa/parser/cxfa_locale.h b/xfa/fxfa/parser/cxfa_locale.h
index 67bee33..18c2f99 100644
--- a/xfa/fxfa/parser/cxfa_locale.h
+++ b/xfa/fxfa/parser/cxfa_locale.h
@@ -11,8 +11,11 @@
 
 class CXFA_Locale final : public CXFA_Node {
  public:
-  CXFA_Locale(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Locale() override;
+
+ private:
+  CXFA_Locale(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LOCALE_H_
diff --git a/xfa/fxfa/parser/cxfa_localeset.h b/xfa/fxfa/parser/cxfa_localeset.h
index dc6521a..6457015 100644
--- a/xfa/fxfa/parser/cxfa_localeset.h
+++ b/xfa/fxfa/parser/cxfa_localeset.h
@@ -11,8 +11,11 @@
 
 class CXFA_LocaleSet final : public CXFA_Node {
  public:
-  CXFA_LocaleSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_LocaleSet() override;
+
+ private:
+  CXFA_LocaleSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LOCALESET_H_
diff --git a/xfa/fxfa/parser/cxfa_lockdocument.h b/xfa/fxfa/parser/cxfa_lockdocument.h
index 1328d34..8367fc1 100644
--- a/xfa/fxfa/parser/cxfa_lockdocument.h
+++ b/xfa/fxfa/parser/cxfa_lockdocument.h
@@ -11,8 +11,11 @@
 
 class CXFA_LockDocument final : public CXFA_Node {
  public:
-  CXFA_LockDocument(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_LockDocument() override;
+
+ private:
+  CXFA_LockDocument(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LOCKDOCUMENT_H_
diff --git a/xfa/fxfa/parser/cxfa_log.h b/xfa/fxfa/parser/cxfa_log.h
index 27173cd..afc0b0a 100644
--- a/xfa/fxfa/parser/cxfa_log.h
+++ b/xfa/fxfa/parser/cxfa_log.h
@@ -11,8 +11,11 @@
 
 class CXFA_Log final : public CXFA_Node {
  public:
-  CXFA_Log(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Log() override;
+
+ private:
+  CXFA_Log(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_LOG_H_
diff --git a/xfa/fxfa/parser/cxfa_manifest.h b/xfa/fxfa/parser/cxfa_manifest.h
index d5ca05f..b77ee35 100644
--- a/xfa/fxfa/parser/cxfa_manifest.h
+++ b/xfa/fxfa/parser/cxfa_manifest.h
@@ -11,8 +11,11 @@
 
 class CXFA_Manifest final : public CXFA_Node {
  public:
-  CXFA_Manifest(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Manifest() override;
+
+ private:
+  CXFA_Manifest(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MANIFEST_H_
diff --git a/xfa/fxfa/parser/cxfa_map.h b/xfa/fxfa/parser/cxfa_map.h
index f8e0797..1a63178 100644
--- a/xfa/fxfa/parser/cxfa_map.h
+++ b/xfa/fxfa/parser/cxfa_map.h
@@ -11,8 +11,11 @@
 
 class CXFA_Map final : public CXFA_Node {
  public:
-  CXFA_Map(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Map() override;
+
+ private:
+  CXFA_Map(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MAP_H_
diff --git a/xfa/fxfa/parser/cxfa_margin.h b/xfa/fxfa/parser/cxfa_margin.h
index 813bdfe..bb32da9 100644
--- a/xfa/fxfa/parser/cxfa_margin.h
+++ b/xfa/fxfa/parser/cxfa_margin.h
@@ -11,7 +11,7 @@
 
 class CXFA_Margin final : public CXFA_Node {
  public:
-  CXFA_Margin(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Margin() override;
 
   float GetLeftInset() const;
@@ -23,6 +23,9 @@
   Optional<float> TryTopInset() const;
   Optional<float> TryRightInset() const;
   Optional<float> TryBottomInset() const;
+
+ private:
+  CXFA_Margin(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MARGIN_H_
diff --git a/xfa/fxfa/parser/cxfa_mdp.h b/xfa/fxfa/parser/cxfa_mdp.h
index 79b1480..c08b0c6 100644
--- a/xfa/fxfa/parser/cxfa_mdp.h
+++ b/xfa/fxfa/parser/cxfa_mdp.h
@@ -11,8 +11,11 @@
 
 class CXFA_Mdp final : public CXFA_Node {
  public:
-  CXFA_Mdp(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Mdp() override;
+
+ private:
+  CXFA_Mdp(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MDP_H_
diff --git a/xfa/fxfa/parser/cxfa_medium.h b/xfa/fxfa/parser/cxfa_medium.h
index 49be83f..7831cb4 100644
--- a/xfa/fxfa/parser/cxfa_medium.h
+++ b/xfa/fxfa/parser/cxfa_medium.h
@@ -11,8 +11,11 @@
 
 class CXFA_Medium final : public CXFA_Node {
  public:
-  CXFA_Medium(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Medium() override;
+
+ private:
+  CXFA_Medium(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MEDIUM_H_
diff --git a/xfa/fxfa/parser/cxfa_mediuminfo.h b/xfa/fxfa/parser/cxfa_mediuminfo.h
index 65e58df..0cdabd3 100644
--- a/xfa/fxfa/parser/cxfa_mediuminfo.h
+++ b/xfa/fxfa/parser/cxfa_mediuminfo.h
@@ -11,8 +11,11 @@
 
 class CXFA_MediumInfo final : public CXFA_Node {
  public:
-  CXFA_MediumInfo(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_MediumInfo() override;
+
+ private:
+  CXFA_MediumInfo(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MEDIUMINFO_H_
diff --git a/xfa/fxfa/parser/cxfa_meridiem.h b/xfa/fxfa/parser/cxfa_meridiem.h
index 40c956c..3e51845 100644
--- a/xfa/fxfa/parser/cxfa_meridiem.h
+++ b/xfa/fxfa/parser/cxfa_meridiem.h
@@ -11,8 +11,11 @@
 
 class CXFA_Meridiem final : public CXFA_Node {
  public:
-  CXFA_Meridiem(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Meridiem() override;
+
+ private:
+  CXFA_Meridiem(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MERIDIEM_H_
diff --git a/xfa/fxfa/parser/cxfa_meridiemnames.h b/xfa/fxfa/parser/cxfa_meridiemnames.h
index 00fbbb7..8816fcb 100644
--- a/xfa/fxfa/parser/cxfa_meridiemnames.h
+++ b/xfa/fxfa/parser/cxfa_meridiemnames.h
@@ -11,8 +11,11 @@
 
 class CXFA_MeridiemNames final : public CXFA_Node {
  public:
-  CXFA_MeridiemNames(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_MeridiemNames() override;
+
+ private:
+  CXFA_MeridiemNames(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MERIDIEMNAMES_H_
diff --git a/xfa/fxfa/parser/cxfa_message.h b/xfa/fxfa/parser/cxfa_message.h
index 81cb751..f290eff 100644
--- a/xfa/fxfa/parser/cxfa_message.h
+++ b/xfa/fxfa/parser/cxfa_message.h
@@ -11,8 +11,11 @@
 
 class CXFA_Message final : public CXFA_Node {
  public:
-  CXFA_Message(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Message() override;
+
+ private:
+  CXFA_Message(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MESSAGE_H_
diff --git a/xfa/fxfa/parser/cxfa_messaging.h b/xfa/fxfa/parser/cxfa_messaging.h
index 86e16f3..da3e1d1 100644
--- a/xfa/fxfa/parser/cxfa_messaging.h
+++ b/xfa/fxfa/parser/cxfa_messaging.h
@@ -11,8 +11,11 @@
 
 class CXFA_Messaging final : public CXFA_Node {
  public:
-  CXFA_Messaging(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Messaging() override;
+
+ private:
+  CXFA_Messaging(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MESSAGING_H_
diff --git a/xfa/fxfa/parser/cxfa_mode.h b/xfa/fxfa/parser/cxfa_mode.h
index 46675db..5c5834d 100644
--- a/xfa/fxfa/parser/cxfa_mode.h
+++ b/xfa/fxfa/parser/cxfa_mode.h
@@ -11,8 +11,11 @@
 
 class CXFA_Mode final : public CXFA_Node {
  public:
-  CXFA_Mode(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Mode() override;
+
+ private:
+  CXFA_Mode(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MODE_H_
diff --git a/xfa/fxfa/parser/cxfa_modifyannots.h b/xfa/fxfa/parser/cxfa_modifyannots.h
index c92b05b..56eae9e 100644
--- a/xfa/fxfa/parser/cxfa_modifyannots.h
+++ b/xfa/fxfa/parser/cxfa_modifyannots.h
@@ -11,8 +11,11 @@
 
 class CXFA_ModifyAnnots final : public CXFA_Node {
  public:
-  CXFA_ModifyAnnots(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ModifyAnnots() override;
+
+ private:
+  CXFA_ModifyAnnots(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MODIFYANNOTS_H_
diff --git a/xfa/fxfa/parser/cxfa_month.h b/xfa/fxfa/parser/cxfa_month.h
index f63095d..7779e75 100644
--- a/xfa/fxfa/parser/cxfa_month.h
+++ b/xfa/fxfa/parser/cxfa_month.h
@@ -11,8 +11,11 @@
 
 class CXFA_Month final : public CXFA_Node {
  public:
-  CXFA_Month(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Month() override;
+
+ private:
+  CXFA_Month(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MONTH_H_
diff --git a/xfa/fxfa/parser/cxfa_monthnames.h b/xfa/fxfa/parser/cxfa_monthnames.h
index cf0c331..e1c9c3e 100644
--- a/xfa/fxfa/parser/cxfa_monthnames.h
+++ b/xfa/fxfa/parser/cxfa_monthnames.h
@@ -11,8 +11,11 @@
 
 class CXFA_MonthNames final : public CXFA_Node {
  public:
-  CXFA_MonthNames(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_MonthNames() override;
+
+ private:
+  CXFA_MonthNames(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MONTHNAMES_H_
diff --git a/xfa/fxfa/parser/cxfa_msgid.h b/xfa/fxfa/parser/cxfa_msgid.h
index 4c166d7..b4a272c 100644
--- a/xfa/fxfa/parser/cxfa_msgid.h
+++ b/xfa/fxfa/parser/cxfa_msgid.h
@@ -11,8 +11,11 @@
 
 class CXFA_MsgId final : public CXFA_Node {
  public:
-  CXFA_MsgId(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_MsgId() override;
+
+ private:
+  CXFA_MsgId(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_MSGID_H_
diff --git a/xfa/fxfa/parser/cxfa_nameattr.h b/xfa/fxfa/parser/cxfa_nameattr.h
index f346bf6..75cfa19 100644
--- a/xfa/fxfa/parser/cxfa_nameattr.h
+++ b/xfa/fxfa/parser/cxfa_nameattr.h
@@ -11,8 +11,11 @@
 
 class CXFA_NameAttr final : public CXFA_Node {
  public:
-  CXFA_NameAttr(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NameAttr() override;
+
+ private:
+  CXFA_NameAttr(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NAMEATTR_H_
diff --git a/xfa/fxfa/parser/cxfa_neverembed.h b/xfa/fxfa/parser/cxfa_neverembed.h
index 70f90a3..a63bb09 100644
--- a/xfa/fxfa/parser/cxfa_neverembed.h
+++ b/xfa/fxfa/parser/cxfa_neverembed.h
@@ -11,8 +11,11 @@
 
 class CXFA_NeverEmbed final : public CXFA_Node {
  public:
-  CXFA_NeverEmbed(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NeverEmbed() override;
+
+ private:
+  CXFA_NeverEmbed(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NEVEREMBED_H_
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index d954ca5..1fb1658 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -813,46 +813,61 @@
 
 }  // namespace
 
-class CXFA_WidgetLayoutData {
+class CXFA_WidgetLayoutData
+    : public cppgc::GarbageCollected<CXFA_WidgetLayoutData> {
  public:
-  CXFA_WidgetLayoutData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   virtual ~CXFA_WidgetLayoutData() = default;
 
+  virtual void Trace(cppgc::Visitor* visitor) const {}
+
   virtual CXFA_FieldLayoutData* AsFieldLayoutData() { return nullptr; }
   virtual CXFA_ImageLayoutData* AsImageLayoutData() { return nullptr; }
   virtual CXFA_TextLayoutData* AsTextLayoutData() { return nullptr; }
 
   float m_fWidgetHeight = -1.0f;
+
+ protected:
+  CXFA_WidgetLayoutData() = default;
 };
 
 class CXFA_TextLayoutData final : public CXFA_WidgetLayoutData {
  public:
-  CXFA_TextLayoutData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TextLayoutData() override = default;
 
+  void Trace(cppgc::Visitor* visitor) const override {
+    CXFA_WidgetLayoutData::Trace(visitor);
+    visitor->Trace(m_pTextLayout);
+    visitor->Trace(m_pTextProvider);
+  }
+
   CXFA_TextLayoutData* AsTextLayoutData() override { return this; }
 
-  CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
-  CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
+  CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout; }
+  CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider; }
 
   void LoadText(CXFA_FFDoc* doc, CXFA_Node* pNode) {
     if (m_pTextLayout)
       return;
 
-    m_pTextProvider =
-        std::make_unique<CXFA_TextProvider>(pNode, XFA_TEXTPROVIDERTYPE_Text);
-    m_pTextLayout =
-        std::make_unique<CXFA_TextLayout>(doc, m_pTextProvider.get());
+    m_pTextProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
+        doc->GetHeap()->GetAllocationHandle(), pNode,
+        XFA_TEXTPROVIDERTYPE_Text);
+    m_pTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
+        doc->GetHeap()->GetAllocationHandle(), doc, m_pTextProvider);
   }
 
  private:
-  std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
-  std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
+  CXFA_TextLayoutData() = default;
+
+  cppgc::Member<CXFA_TextLayout> m_pTextLayout;
+  cppgc::Member<CXFA_TextProvider> m_pTextProvider;
 };
 
 class CXFA_ImageLayoutData final : public CXFA_WidgetLayoutData {
  public:
-  CXFA_ImageLayoutData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ImageLayoutData() override = default;
 
   CXFA_ImageLayoutData* AsImageLayoutData() override { return this; }
@@ -878,13 +893,21 @@
   int32_t m_iImageXDpi = 0;
   int32_t m_iImageYDpi = 0;
   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+
+ private:
+  CXFA_ImageLayoutData() = default;
 };
 
 class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
  public:
-  CXFA_FieldLayoutData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FieldLayoutData() override = default;
 
+  void Trace(cppgc::Visitor* visitor) const override {
+    CXFA_WidgetLayoutData::Trace(visitor);
+    visitor->Trace(m_pCapTextLayout);
+    visitor->Trace(m_pCapTextProvider);
+  }
   CXFA_FieldLayoutData* AsFieldLayoutData() override { return this; }
 
   virtual CXFA_ImageEditData* AsImageEditData() { return nullptr; }
@@ -897,30 +920,37 @@
     if (!caption || caption->IsHidden())
       return false;
 
-    m_pCapTextProvider = std::make_unique<CXFA_TextProvider>(
-        pNode, XFA_TEXTPROVIDERTYPE_Caption);
-    m_pCapTextLayout =
-        std::make_unique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
+    m_pCapTextProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
+        doc->GetHeap()->GetAllocationHandle(), pNode,
+        XFA_TEXTPROVIDERTYPE_Caption);
+    m_pCapTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
+        doc->GetHeap()->GetAllocationHandle(), doc, m_pCapTextProvider);
     return true;
   }
 
-  std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
-  std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
+  cppgc::Member<CXFA_TextLayout> m_pCapTextLayout;
+  cppgc::Member<CXFA_TextProvider> m_pCapTextProvider;
   std::unique_ptr<CFDE_TextOut> m_pTextOut;
   std::vector<float> m_FieldSplitArray;
+
+ protected:
+  CXFA_FieldLayoutData() = default;
 };
 
 class CXFA_TextEditData final : public CXFA_FieldLayoutData {
  public:
-  CXFA_TextEditData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TextEditData() override = default;
 
   CXFA_TextEditData* AsTextEditData() override { return this; }
+
+ protected:
+  CXFA_TextEditData() = default;
 };
 
 class CXFA_ImageEditData final : public CXFA_FieldLayoutData {
  public:
-  CXFA_ImageEditData() = default;
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ImageEditData() override = default;
 
   CXFA_ImageEditData* AsImageEditData() override { return this; }
@@ -946,6 +976,9 @@
   int32_t m_iImageXDpi = 0;
   int32_t m_iImageYDpi = 0;
   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+
+ private:
+  CXFA_ImageEditData() = default;
 };
 
 CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
@@ -966,6 +999,16 @@
 
 CXFA_Node::~CXFA_Node() = default;
 
+void CXFA_Node::Trace(cppgc::Visitor* visitor) const {
+  CXFA_Object::Trace(visitor);
+  GCedTreeNodeMixin<CXFA_Node>::Trace(visitor);
+  visitor->Trace(m_pAuxNode);
+  for (const auto& node : binding_nodes_)
+    visitor->Trace(node);
+  visitor->Trace(m_pLayoutData);
+  visitor->Trace(ui_);
+}
+
 CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
   CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
   if (!pClone)
@@ -1255,12 +1298,16 @@
   return GetBindingNode();
 }
 
+std::vector<CXFA_Node*> CXFA_Node::GetBindItemsCopy() const {
+  return std::vector<CXFA_Node*>(binding_nodes_.begin(), binding_nodes_.end());
+}
+
 int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
   ASSERT(pFormNode);
 
   if (BindsFormItems()) {
     bool found = false;
-    for (auto* v : binding_nodes_) {
+    for (const auto& v : binding_nodes_) {
       if (v == pFormNode) {
         found = true;
         break;
@@ -1279,11 +1326,9 @@
   if (pOldFormItem == pFormNode)
     return 1;
 
-  std::vector<CXFA_Node*> items;
-  items.push_back(pOldFormItem);
-  items.push_back(pFormNode);
-  binding_nodes_ = std::move(items);
-
+  binding_nodes_.clear();
+  binding_nodes_.push_back(pOldFormItem);
+  binding_nodes_.push_back(pFormNode);
   m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
   return 2;
 }
@@ -1576,7 +1621,7 @@
     return;
 
   pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren);
-  TreeNode<CXFA_Node>::RemoveChild(pNode);
+  GCedTreeNodeMixin<CXFA_Node>::RemoveChild(pNode);
   OnRemoved(bNotify);
 
   if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
@@ -2734,7 +2779,7 @@
   pContext->SetEventParam(pEventParam);
   pContext->SetRunAtType(script->GetRunAt());
 
-  std::vector<CXFA_Node*> refNodes;
+  std::vector<cppgc::Persistent<CXFA_Node>> refNodes;
   if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
       pEventParam->m_eType == XFA_EVENT_Calculate) {
     pContext->SetNodesOfRunScript(&refNodes);
@@ -3134,7 +3179,7 @@
   const bool bVert = iCapPlacement == XFA_AttributeValue::Top ||
                      iCapPlacement == XFA_AttributeValue::Bottom;
   CXFA_TextLayout* pCapTextLayout =
-      m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout.get();
+      m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout;
   if (pCapTextLayout) {
     if (!bVert && GetFFWidgetType() != XFA_FFWidgetType::kButton)
       pszCap->width = fCapReserve;
@@ -3400,12 +3445,12 @@
 }
 
 bool CXFA_Node::LoadImageImage(CXFA_FFDoc* doc) {
-  InitLayoutData();
+  InitLayoutData(doc);
   return m_pLayoutData->AsImageLayoutData()->LoadImageData(doc, this);
 }
 
 bool CXFA_Node::LoadImageEditImage(CXFA_FFDoc* doc) {
-  InitLayoutData();
+  InitLayoutData(doc);
   return m_pLayoutData->AsFieldLayoutData()->AsImageEditData()->LoadImageData(
       doc, this);
 }
@@ -3470,7 +3515,7 @@
 void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
                                   float* pCalcWidth,
                                   float* pCalcHeight) {
-  InitLayoutData();
+  InitLayoutData(doc);
 
   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
     m_pLayoutData->m_fWidgetHeight = TryHeight().value_or(-1);
@@ -3780,37 +3825,43 @@
   return fSplitHeight;
 }
 
-void CXFA_Node::InitLayoutData() {
+void CXFA_Node::InitLayoutData(CXFA_FFDoc* doc) {
   if (m_pLayoutData)
     return;
 
   switch (GetFFWidgetType()) {
     case XFA_FFWidgetType::kText:
-      m_pLayoutData = std::make_unique<CXFA_TextLayoutData>();
+      m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextLayoutData>(
+          doc->GetHeap()->GetAllocationHandle());
       return;
     case XFA_FFWidgetType::kTextEdit:
-      m_pLayoutData = std::make_unique<CXFA_TextEditData>();
+      m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextEditData>(
+          doc->GetHeap()->GetAllocationHandle());
       return;
     case XFA_FFWidgetType::kImage:
-      m_pLayoutData = std::make_unique<CXFA_ImageLayoutData>();
+      m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageLayoutData>(
+          doc->GetHeap()->GetAllocationHandle());
       return;
     case XFA_FFWidgetType::kImageEdit:
-      m_pLayoutData = std::make_unique<CXFA_ImageEditData>();
+      m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageEditData>(
+          doc->GetHeap()->GetAllocationHandle());
       return;
     default:
       break;
   }
   if (GetElementType() == XFA_Element::Field) {
-    m_pLayoutData = std::make_unique<CXFA_FieldLayoutData>();
+    m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_FieldLayoutData>(
+        doc->GetHeap()->GetAllocationHandle());
     return;
   }
-  m_pLayoutData = std::make_unique<CXFA_WidgetLayoutData>();
+  m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_WidgetLayoutData>(
+      doc->GetHeap()->GetAllocationHandle());
 }
 
 void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
                                 float* pCalcWidth,
                                 float* pCalcHeight) {
-  InitLayoutData();
+  InitLayoutData(doc);
 
   CXFA_TextLayoutData* pTextLayoutData = m_pLayoutData->AsTextLayoutData();
   pTextLayoutData->LoadText(doc, this);
@@ -3852,14 +3903,13 @@
 }
 
 bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
-  InitLayoutData();
+  InitLayoutData(doc);
   return m_pLayoutData->AsFieldLayoutData()->LoadCaption(doc, this);
 }
 
 CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
-  return m_pLayoutData
-             ? m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout.get()
-             : nullptr;
+  return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout
+                       : nullptr;
 }
 
 CXFA_TextLayout* CXFA_Node::GetTextLayout() {
@@ -5086,919 +5136,1222 @@
 }
 
 // static
-std::unique_ptr<CXFA_Node> CXFA_Node::Create(CXFA_Document* doc,
-                                             XFA_Element element,
-                                             XFA_PacketType packet) {
-  std::unique_ptr<CXFA_Node> node;
+CXFA_Node* CXFA_Node::Create(CXFA_Document* doc,
+                             XFA_Element element,
+                             XFA_PacketType packet) {
+  CXFA_Node* node = nullptr;
   switch (element) {
     case XFA_Element::Ps:
-      node = std::make_unique<CXFA_Ps>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Ps>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::To:
-      node = std::make_unique<CXFA_To>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_To>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Ui:
-      node = std::make_unique<CXFA_Ui>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Ui>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::RecordSet:
-      node = std::make_unique<CXFA_RecordSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_RecordSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubsetBelow:
-      node = std::make_unique<CXFA_SubsetBelow>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubsetBelow>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubformSet:
-      node = std::make_unique<CXFA_SubformSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubformSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AdobeExtensionLevel:
-      node = std::make_unique<CXFA_AdobeExtensionLevel>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AdobeExtensionLevel>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Typeface:
-      node = std::make_unique<CXFA_Typeface>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Typeface>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Break:
-      node = std::make_unique<CXFA_Break>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Break>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::FontInfo:
-      node = std::make_unique<CXFA_FontInfo>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_FontInfo>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumberPattern:
-      node = std::make_unique<CXFA_NumberPattern>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumberPattern>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DynamicRender:
-      node = std::make_unique<CXFA_DynamicRender>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DynamicRender>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PrintScaling:
-      node = std::make_unique<CXFA_PrintScaling>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PrintScaling>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CheckButton:
-      node = std::make_unique<CXFA_CheckButton>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CheckButton>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DatePatterns:
-      node = std::make_unique<CXFA_DatePatterns>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DatePatterns>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SourceSet:
-      node = std::make_unique<CXFA_SourceSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SourceSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Amd:
-      node = std::make_unique<CXFA_Amd>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Amd>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Arc:
-      node = std::make_unique<CXFA_Arc>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Arc>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Day:
-      node = std::make_unique<CXFA_Day>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Day>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Era:
-      node = std::make_unique<CXFA_Era>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Era>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Jog:
-      node = std::make_unique<CXFA_Jog>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Jog>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Log:
-      node = std::make_unique<CXFA_Log>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Log>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Map:
-      node = std::make_unique<CXFA_Map>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Map>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Mdp:
-      node = std::make_unique<CXFA_Mdp>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Mdp>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::BreakBefore:
-      node = std::make_unique<CXFA_BreakBefore>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_BreakBefore>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Oid:
-      node = std::make_unique<CXFA_Oid>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Oid>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Pcl:
-      node = std::make_unique<CXFA_Pcl>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Pcl>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Pdf:
-      node = std::make_unique<CXFA_Pdf>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Pdf>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Ref:
-      node = std::make_unique<CXFA_Ref>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Ref>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Uri:
-      node = std::make_unique<CXFA_Uri>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Uri>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Xdc:
-      node = std::make_unique<CXFA_Xdc>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Xdc>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Xdp:
-      node = std::make_unique<CXFA_Xdp>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Xdp>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Xfa:
-      node = std::make_unique<CXFA_Xfa>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Xfa>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Xsl:
-      node = std::make_unique<CXFA_Xsl>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Xsl>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Zpl:
-      node = std::make_unique<CXFA_Zpl>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Zpl>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Cache:
-      node = std::make_unique<CXFA_Cache>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Cache>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Margin:
-      node = std::make_unique<CXFA_Margin>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Margin>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::KeyUsage:
-      node = std::make_unique<CXFA_KeyUsage>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_KeyUsage>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Exclude:
-      node = std::make_unique<CXFA_Exclude>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Exclude>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ChoiceList:
-      node = std::make_unique<CXFA_ChoiceList>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ChoiceList>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Level:
-      node = std::make_unique<CXFA_Level>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Level>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::LabelPrinter:
-      node = std::make_unique<CXFA_LabelPrinter>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_LabelPrinter>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CalendarSymbols:
-      node = std::make_unique<CXFA_CalendarSymbols>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CalendarSymbols>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Para:
-      node = std::make_unique<CXFA_Para>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Para>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Part:
-      node = std::make_unique<CXFA_Part>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Part>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Pdfa:
-      node = std::make_unique<CXFA_Pdfa>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Pdfa>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Filter:
-      node = std::make_unique<CXFA_Filter>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Filter>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Present:
-      node = std::make_unique<CXFA_Present>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Present>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Pagination:
-      node = std::make_unique<CXFA_Pagination>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Pagination>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Encoding:
-      node = std::make_unique<CXFA_Encoding>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Encoding>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Event:
-      node = std::make_unique<CXFA_Event>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Event>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Whitespace:
-      node = std::make_unique<CXFA_Whitespace>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Whitespace>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DefaultUi:
-      node = std::make_unique<CXFA_DefaultUi>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DefaultUi>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DataModel:
-      node = std::make_unique<CXFA_DataModel>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DataModel>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Barcode:
-      node = std::make_unique<CXFA_Barcode>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Barcode>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::TimePattern:
-      node = std::make_unique<CXFA_TimePattern>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_TimePattern>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::BatchOutput:
-      node = std::make_unique<CXFA_BatchOutput>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_BatchOutput>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Enforce:
-      node = std::make_unique<CXFA_Enforce>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Enforce>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CurrencySymbols:
-      node = std::make_unique<CXFA_CurrencySymbols>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbols>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AddSilentPrint:
-      node = std::make_unique<CXFA_AddSilentPrint>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AddSilentPrint>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Rename:
-      node = std::make_unique<CXFA_Rename>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Rename>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Operation:
-      node = std::make_unique<CXFA_Operation>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Operation>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Typefaces:
-      node = std::make_unique<CXFA_Typefaces>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Typefaces>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubjectDNs:
-      node = std::make_unique<CXFA_SubjectDNs>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubjectDNs>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Issuers:
-      node = std::make_unique<CXFA_Issuers>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Issuers>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::WsdlConnection:
-      node = std::make_unique<CXFA_WsdlConnection>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_WsdlConnection>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Debug:
-      node = std::make_unique<CXFA_Debug>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Debug>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Delta:
-      node = std::make_unique<CXFA_Delta>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Delta>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EraNames:
-      node = std::make_unique<CXFA_EraNames>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EraNames>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ModifyAnnots:
-      node = std::make_unique<CXFA_ModifyAnnots>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ModifyAnnots>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::StartNode:
-      node = std::make_unique<CXFA_StartNode>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_StartNode>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Button:
-      node = std::make_unique<CXFA_Button>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Button>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Format:
-      node = std::make_unique<CXFA_Format>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Format>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Border:
-      node = std::make_unique<CXFA_Border>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Border>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Area:
-      node = std::make_unique<CXFA_Area>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Area>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Hyphenation:
-      node = std::make_unique<CXFA_Hyphenation>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Hyphenation>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Text:
-      node = std::make_unique<CXFA_Text>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Text>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Time:
-      node = std::make_unique<CXFA_Time>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Time>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Type:
-      node = std::make_unique<CXFA_Type>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Type>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Overprint:
-      node = std::make_unique<CXFA_Overprint>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Overprint>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Certificates:
-      node = std::make_unique<CXFA_Certificates>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Certificates>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EncryptionMethods:
-      node = std::make_unique<CXFA_EncryptionMethods>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethods>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SetProperty:
-      node = std::make_unique<CXFA_SetProperty>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SetProperty>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PrinterName:
-      node = std::make_unique<CXFA_PrinterName>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PrinterName>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::StartPage:
-      node = std::make_unique<CXFA_StartPage>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_StartPage>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PageOffset:
-      node = std::make_unique<CXFA_PageOffset>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PageOffset>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DateTime:
-      node = std::make_unique<CXFA_DateTime>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DateTime>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Comb:
-      node = std::make_unique<CXFA_Comb>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Comb>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Pattern:
-      node = std::make_unique<CXFA_Pattern>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Pattern>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::IfEmpty:
-      node = std::make_unique<CXFA_IfEmpty>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_IfEmpty>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SuppressBanner:
-      node = std::make_unique<CXFA_SuppressBanner>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SuppressBanner>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::OutputBin:
-      node = std::make_unique<CXFA_OutputBin>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_OutputBin>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Field:
-      node = std::make_unique<CXFA_Field>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Field>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Agent:
-      node = std::make_unique<CXFA_Agent>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Agent>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::OutputXSL:
-      node = std::make_unique<CXFA_OutputXSL>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_OutputXSL>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AdjustData:
-      node = std::make_unique<CXFA_AdjustData>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AdjustData>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AutoSave:
-      node = std::make_unique<CXFA_AutoSave>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AutoSave>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ContentArea:
-      node = std::make_unique<CXFA_ContentArea>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ContentArea>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::WsdlAddress:
-      node = std::make_unique<CXFA_WsdlAddress>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_WsdlAddress>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Solid:
-      node = std::make_unique<CXFA_Solid>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Solid>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DateTimeSymbols:
-      node = std::make_unique<CXFA_DateTimeSymbols>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DateTimeSymbols>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EncryptionLevel:
-      node = std::make_unique<CXFA_EncryptionLevel>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EncryptionLevel>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Edge:
-      node = std::make_unique<CXFA_Edge>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Edge>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Stipple:
-      node = std::make_unique<CXFA_Stipple>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Stipple>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Attributes:
-      node = std::make_unique<CXFA_Attributes>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Attributes>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::VersionControl:
-      node = std::make_unique<CXFA_VersionControl>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_VersionControl>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Meridiem:
-      node = std::make_unique<CXFA_Meridiem>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Meridiem>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ExclGroup:
-      node = std::make_unique<CXFA_ExclGroup>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ExclGroup>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ToolTip:
-      node = std::make_unique<CXFA_ToolTip>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ToolTip>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Compress:
-      node = std::make_unique<CXFA_Compress>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Compress>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Reason:
-      node = std::make_unique<CXFA_Reason>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Reason>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Execute:
-      node = std::make_unique<CXFA_Execute>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Execute>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ContentCopy:
-      node = std::make_unique<CXFA_ContentCopy>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ContentCopy>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DateTimeEdit:
-      node = std::make_unique<CXFA_DateTimeEdit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DateTimeEdit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Config:
-      node = std::make_unique<CXFA_Config>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Config>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Image:
-      node = std::make_unique<CXFA_Image>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Image>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SharpxHTML:
-      node = std::make_unique<CXFA_SharpxHTML>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SharpxHTML>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumberOfCopies:
-      node = std::make_unique<CXFA_NumberOfCopies>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumberOfCopies>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::BehaviorOverride:
-      node = std::make_unique<CXFA_BehaviorOverride>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_BehaviorOverride>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::TimeStamp:
-      node = std::make_unique<CXFA_TimeStamp>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_TimeStamp>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Month:
-      node = std::make_unique<CXFA_Month>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Month>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ViewerPreferences:
-      node = std::make_unique<CXFA_ViewerPreferences>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ViewerPreferences>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ScriptModel:
-      node = std::make_unique<CXFA_ScriptModel>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ScriptModel>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Decimal:
-      node = std::make_unique<CXFA_Decimal>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Decimal>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Subform:
-      node = std::make_unique<CXFA_Subform>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Subform>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Select:
-      node = std::make_unique<CXFA_Select>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Select>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Window:
-      node = std::make_unique<CXFA_Window>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Window>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::LocaleSet:
-      node = std::make_unique<CXFA_LocaleSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_LocaleSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Handler:
-      node = std::make_unique<CXFA_Handler>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Handler>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Presence:
-      node = std::make_unique<CXFA_Presence>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Presence>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Record:
-      node = std::make_unique<CXFA_Record>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Record>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Embed:
-      node = std::make_unique<CXFA_Embed>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Embed>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Version:
-      node = std::make_unique<CXFA_Version>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Version>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Command:
-      node = std::make_unique<CXFA_Command>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Command>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Copies:
-      node = std::make_unique<CXFA_Copies>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Copies>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Staple:
-      node = std::make_unique<CXFA_Staple>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Staple>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubmitFormat:
-      node = std::make_unique<CXFA_SubmitFormat>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubmitFormat>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Boolean:
-      node = std::make_unique<CXFA_Boolean>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Boolean>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Message:
-      node = std::make_unique<CXFA_Message>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Message>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Output:
-      node = std::make_unique<CXFA_Output>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Output>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PsMap:
-      node = std::make_unique<CXFA_PsMap>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PsMap>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ExcludeNS:
-      node = std::make_unique<CXFA_ExcludeNS>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ExcludeNS>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Assist:
-      node = std::make_unique<CXFA_Assist>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Assist>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Picture:
-      node = std::make_unique<CXFA_Picture>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Picture>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Traversal:
-      node = std::make_unique<CXFA_Traversal>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Traversal>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SilentPrint:
-      node = std::make_unique<CXFA_SilentPrint>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SilentPrint>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::WebClient:
-      node = std::make_unique<CXFA_WebClient>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_WebClient>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Producer:
-      node = std::make_unique<CXFA_Producer>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Producer>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Corner:
-      node = std::make_unique<CXFA_Corner>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Corner>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::MsgId:
-      node = std::make_unique<CXFA_MsgId>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_MsgId>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Color:
-      node = std::make_unique<CXFA_Color>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Color>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Keep:
-      node = std::make_unique<CXFA_Keep>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Keep>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Query:
-      node = std::make_unique<CXFA_Query>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Query>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Insert:
-      node = std::make_unique<CXFA_Insert>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Insert>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ImageEdit:
-      node = std::make_unique<CXFA_ImageEdit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ImageEdit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Validate:
-      node = std::make_unique<CXFA_Validate>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Validate>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DigestMethods:
-      node = std::make_unique<CXFA_DigestMethods>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DigestMethods>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumberPatterns:
-      node = std::make_unique<CXFA_NumberPatterns>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumberPatterns>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PageSet:
-      node = std::make_unique<CXFA_PageSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PageSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Integer:
-      node = std::make_unique<CXFA_Integer>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Integer>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SoapAddress:
-      node = std::make_unique<CXFA_SoapAddress>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SoapAddress>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Equate:
-      node = std::make_unique<CXFA_Equate>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Equate>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::FormFieldFilling:
-      node = std::make_unique<CXFA_FormFieldFilling>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_FormFieldFilling>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PageRange:
-      node = std::make_unique<CXFA_PageRange>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PageRange>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Update:
-      node = std::make_unique<CXFA_Update>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Update>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ConnectString:
-      node = std::make_unique<CXFA_ConnectString>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ConnectString>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Mode:
-      node = std::make_unique<CXFA_Mode>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Mode>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Layout:
-      node = std::make_unique<CXFA_Layout>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Layout>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Sharpxml:
-      node = std::make_unique<CXFA_Sharpxml>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Sharpxml>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::XsdConnection:
-      node = std::make_unique<CXFA_XsdConnection>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_XsdConnection>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Traverse:
-      node = std::make_unique<CXFA_Traverse>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Traverse>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Encodings:
-      node = std::make_unique<CXFA_Encodings>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Encodings>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Template:
-      node = std::make_unique<CXFA_Template>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Template>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Acrobat:
-      node = std::make_unique<CXFA_Acrobat>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Acrobat>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ValidationMessaging:
-      node = std::make_unique<CXFA_ValidationMessaging>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ValidationMessaging>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Signing:
-      node = std::make_unique<CXFA_Signing>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Signing>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Script:
-      node = std::make_unique<CXFA_Script>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Script>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AddViewerPreferences:
-      node = std::make_unique<CXFA_AddViewerPreferences>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AddViewerPreferences>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AlwaysEmbed:
-      node = std::make_unique<CXFA_AlwaysEmbed>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AlwaysEmbed>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PasswordEdit:
-      node = std::make_unique<CXFA_PasswordEdit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PasswordEdit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumericEdit:
-      node = std::make_unique<CXFA_NumericEdit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumericEdit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EncryptionMethod:
-      node = std::make_unique<CXFA_EncryptionMethod>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethod>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Change:
-      node = std::make_unique<CXFA_Change>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Change>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PageArea:
-      node = std::make_unique<CXFA_PageArea>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PageArea>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubmitUrl:
-      node = std::make_unique<CXFA_SubmitUrl>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubmitUrl>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Oids:
-      node = std::make_unique<CXFA_Oids>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Oids>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Signature:
-      node = std::make_unique<CXFA_Signature>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Signature>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ADBE_JSConsole:
-      node = std::make_unique<CXFA_ADBE_JSConsole>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSConsole>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Caption:
-      node = std::make_unique<CXFA_Caption>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Caption>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Relevant:
-      node = std::make_unique<CXFA_Relevant>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Relevant>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::FlipLabel:
-      node = std::make_unique<CXFA_FlipLabel>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_FlipLabel>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ExData:
-      node = std::make_unique<CXFA_ExData>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ExData>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DayNames:
-      node = std::make_unique<CXFA_DayNames>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DayNames>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SoapAction:
-      node = std::make_unique<CXFA_SoapAction>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SoapAction>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DefaultTypeface:
-      node = std::make_unique<CXFA_DefaultTypeface>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DefaultTypeface>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Manifest:
-      node = std::make_unique<CXFA_Manifest>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Manifest>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Overflow:
-      node = std::make_unique<CXFA_Overflow>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Overflow>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Linear:
-      node = std::make_unique<CXFA_Linear>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Linear>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CurrencySymbol:
-      node = std::make_unique<CXFA_CurrencySymbol>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbol>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Delete:
-      node = std::make_unique<CXFA_Delete>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Delete>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DigestMethod:
-      node = std::make_unique<CXFA_DigestMethod>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DigestMethod>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::InstanceManager:
-      node = std::make_unique<CXFA_InstanceManager>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_InstanceManager>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EquateRange:
-      node = std::make_unique<CXFA_EquateRange>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EquateRange>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Medium:
-      node = std::make_unique<CXFA_Medium>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Medium>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::TextEdit:
-      node = std::make_unique<CXFA_TextEdit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_TextEdit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::TemplateCache:
-      node = std::make_unique<CXFA_TemplateCache>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_TemplateCache>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CompressObjectStream:
-      node = std::make_unique<CXFA_CompressObjectStream>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CompressObjectStream>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DataValue:
-      node = std::make_unique<CXFA_DataValue>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DataValue>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AccessibleContent:
-      node = std::make_unique<CXFA_AccessibleContent>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AccessibleContent>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::IncludeXDPContent:
-      node = std::make_unique<CXFA_IncludeXDPContent>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_IncludeXDPContent>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::XmlConnection:
-      node = std::make_unique<CXFA_XmlConnection>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_XmlConnection>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ValidateApprovalSignatures:
-      node = std::make_unique<CXFA_ValidateApprovalSignatures>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ValidateApprovalSignatures>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SignData:
-      node = std::make_unique<CXFA_SignData>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SignData>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Packets:
-      node = std::make_unique<CXFA_Packets>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Packets>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DatePattern:
-      node = std::make_unique<CXFA_DatePattern>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DatePattern>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DuplexOption:
-      node = std::make_unique<CXFA_DuplexOption>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DuplexOption>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Base:
-      node = std::make_unique<CXFA_Base>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Base>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Bind:
-      node = std::make_unique<CXFA_Bind>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Bind>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Compression:
-      node = std::make_unique<CXFA_Compression>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Compression>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::User:
-      node = std::make_unique<CXFA_User>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_User>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Rectangle:
-      node = std::make_unique<CXFA_Rectangle>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Rectangle>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EffectiveOutputPolicy:
-      node = std::make_unique<CXFA_EffectiveOutputPolicy>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EffectiveOutputPolicy>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ADBE_JSDebugger:
-      node = std::make_unique<CXFA_ADBE_JSDebugger>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSDebugger>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Acrobat7:
-      node = std::make_unique<CXFA_Acrobat7>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Acrobat7>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Interactive:
-      node = std::make_unique<CXFA_Interactive>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Interactive>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Locale:
-      node = std::make_unique<CXFA_Locale>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Locale>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CurrentPage:
-      node = std::make_unique<CXFA_CurrentPage>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CurrentPage>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Data:
-      node = std::make_unique<CXFA_Data>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Data>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Date:
-      node = std::make_unique<CXFA_Date>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Date>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Desc:
-      node = std::make_unique<CXFA_Desc>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Desc>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Encrypt:
-      node = std::make_unique<CXFA_Encrypt>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Encrypt>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Draw:
-      node = std::make_unique<CXFA_Draw>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Draw>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Encryption:
-      node = std::make_unique<CXFA_Encryption>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Encryption>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::MeridiemNames:
-      node = std::make_unique<CXFA_MeridiemNames>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_MeridiemNames>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Messaging:
-      node = std::make_unique<CXFA_Messaging>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Messaging>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Speak:
-      node = std::make_unique<CXFA_Speak>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Speak>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DataGroup:
-      node = std::make_unique<CXFA_DataGroup>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DataGroup>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Common:
-      node = std::make_unique<CXFA_Common>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Common>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Sharptext:
-      node = std::make_unique<CXFA_Sharptext>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Sharptext>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PaginationOverride:
-      node = std::make_unique<CXFA_PaginationOverride>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PaginationOverride>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Reasons:
-      node = std::make_unique<CXFA_Reasons>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Reasons>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SignatureProperties:
-      node = std::make_unique<CXFA_SignatureProperties>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SignatureProperties>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Threshold:
-      node = std::make_unique<CXFA_Threshold>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Threshold>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::AppearanceFilter:
-      node = std::make_unique<CXFA_AppearanceFilter>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_AppearanceFilter>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Fill:
-      node = std::make_unique<CXFA_Fill>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Fill>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Font:
-      node = std::make_unique<CXFA_Font>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Font>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Form:
-      node = std::make_unique<CXFA_Form>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Form>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::MediumInfo:
-      node = std::make_unique<CXFA_MediumInfo>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_MediumInfo>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Certificate:
-      node = std::make_unique<CXFA_Certificate>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Certificate>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Password:
-      node = std::make_unique<CXFA_Password>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Password>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::RunScripts:
-      node = std::make_unique<CXFA_RunScripts>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_RunScripts>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Trace:
-      node = std::make_unique<CXFA_Trace>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Trace>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Float:
-      node = std::make_unique<CXFA_Float>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Float>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::RenderPolicy:
-      node = std::make_unique<CXFA_RenderPolicy>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_RenderPolicy>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Destination:
-      node = std::make_unique<CXFA_Destination>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Destination>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Value:
-      node = std::make_unique<CXFA_Value>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Value>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Bookend:
-      node = std::make_unique<CXFA_Bookend>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Bookend>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ExObject:
-      node = std::make_unique<CXFA_ExObject>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ExObject>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::OpenAction:
-      node = std::make_unique<CXFA_OpenAction>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_OpenAction>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NeverEmbed:
-      node = std::make_unique<CXFA_NeverEmbed>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NeverEmbed>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::BindItems:
-      node = std::make_unique<CXFA_BindItems>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_BindItems>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Calculate:
-      node = std::make_unique<CXFA_Calculate>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Calculate>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Print:
-      node = std::make_unique<CXFA_Print>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Print>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Extras:
-      node = std::make_unique<CXFA_Extras>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Extras>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Proto:
-      node = std::make_unique<CXFA_Proto>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Proto>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DSigData:
-      node = std::make_unique<CXFA_DSigData>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DSigData>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Creator:
-      node = std::make_unique<CXFA_Creator>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Creator>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Connect:
-      node = std::make_unique<CXFA_Connect>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Connect>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Permissions:
-      node = std::make_unique<CXFA_Permissions>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Permissions>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::ConnectionSet:
-      node = std::make_unique<CXFA_ConnectionSet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_ConnectionSet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Submit:
-      node = std::make_unique<CXFA_Submit>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Submit>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Range:
-      node = std::make_unique<CXFA_Range>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Range>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Linearized:
-      node = std::make_unique<CXFA_Linearized>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Linearized>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Packet:
-      node = std::make_unique<CXFA_Packet>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Packet>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::RootElement:
-      node = std::make_unique<CXFA_RootElement>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_RootElement>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PlaintextMetadata:
-      node = std::make_unique<CXFA_PlaintextMetadata>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PlaintextMetadata>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumberSymbols:
-      node = std::make_unique<CXFA_NumberSymbols>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumberSymbols>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PrintHighQuality:
-      node = std::make_unique<CXFA_PrintHighQuality>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PrintHighQuality>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Driver:
-      node = std::make_unique<CXFA_Driver>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Driver>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::IncrementalLoad:
-      node = std::make_unique<CXFA_IncrementalLoad>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_IncrementalLoad>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::SubjectDN:
-      node = std::make_unique<CXFA_SubjectDN>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_SubjectDN>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::CompressLogicalStructure:
-      node = std::make_unique<CXFA_CompressLogicalStructure>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_CompressLogicalStructure>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::IncrementalMerge:
-      node = std::make_unique<CXFA_IncrementalMerge>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_IncrementalMerge>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Radial:
-      node = std::make_unique<CXFA_Radial>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Radial>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Variables:
-      node = std::make_unique<CXFA_Variables>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Variables>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::TimePatterns:
-      node = std::make_unique<CXFA_TimePatterns>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_TimePatterns>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::EffectiveInputPolicy:
-      node = std::make_unique<CXFA_EffectiveInputPolicy>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_EffectiveInputPolicy>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NameAttr:
-      node = std::make_unique<CXFA_NameAttr>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NameAttr>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Conformance:
-      node = std::make_unique<CXFA_Conformance>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Conformance>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Transform:
-      node = std::make_unique<CXFA_Transform>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Transform>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::LockDocument:
-      node = std::make_unique<CXFA_LockDocument>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_LockDocument>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::BreakAfter:
-      node = std::make_unique<CXFA_BreakAfter>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_BreakAfter>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Line:
-      node = std::make_unique<CXFA_Line>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Line>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Source:
-      node = std::make_unique<CXFA_Source>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Source>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Occur:
-      node = std::make_unique<CXFA_Occur>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Occur>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::PickTrayByPDFSize:
-      node = std::make_unique<CXFA_PickTrayByPDFSize>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_PickTrayByPDFSize>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::MonthNames:
-      node = std::make_unique<CXFA_MonthNames>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_MonthNames>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Severity:
-      node = std::make_unique<CXFA_Severity>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Severity>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::GroupParent:
-      node = std::make_unique<CXFA_GroupParent>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_GroupParent>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::DocumentAssembly:
-      node = std::make_unique<CXFA_DocumentAssembly>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_DocumentAssembly>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::NumberSymbol:
-      node = std::make_unique<CXFA_NumberSymbol>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_NumberSymbol>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Tagged:
-      node = std::make_unique<CXFA_Tagged>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Tagged>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     case XFA_Element::Items:
-      node = std::make_unique<CXFA_Items>(doc, packet);
+      node = cppgc::MakeGarbageCollected<CXFA_Items>(
+          doc->GetHeap()->GetAllocationHandle(), doc, packet);
       break;
     default:
       NOTREACHED();
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 097a6a1..d18d6db 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -12,10 +12,12 @@
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/tree_node.h"
 #include "core/fxge/fx_dib.h"
+#include "fxjs/gc/gced_tree_node_mixin.h"
 #include "third_party/base/optional.h"
 #include "third_party/base/span.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_ffwidget_type.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
@@ -73,7 +75,7 @@
   XFA_NodeFlag_LayoutGeneratedNode = 1 << 6
 };
 
-class CXFA_Node : public CXFA_Object, public TreeNode<CXFA_Node> {
+class CXFA_Node : public CXFA_Object, public GCedTreeNodeMixin<CXFA_Node> {
  public:
   struct PropertyData {
     XFA_Element property;
@@ -87,12 +89,16 @@
     void* default_value;
   };
 
-  static std::unique_ptr<CXFA_Node> Create(CXFA_Document* doc,
-                                           XFA_Element element,
-                                           XFA_PacketType packet);
+  // Node is created from cppgc heap.
+  static CXFA_Node* Create(CXFA_Document* doc,
+                           XFA_Element element,
+                           XFA_PacketType packet);
 
   ~CXFA_Node() override;
 
+  // CXFA_Object:
+  void Trace(cppgc::Visitor* visitor) const override;
+
   bool HasProperty(XFA_Element property) const;
   bool HasPropertyFlags(XFA_Element property, uint8_t flags) const;
   uint8_t PropertyOccuranceCount(XFA_Element property) const;
@@ -186,7 +192,7 @@
   void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
   CXFA_Node* GetBindData();
   bool HasBindItems() const { return !binding_nodes_.empty(); }
-  std::vector<CXFA_Node*> GetBindItemsCopy() { return binding_nodes_; }
+  std::vector<CXFA_Node*> GetBindItemsCopy() const;
   int32_t AddBindItem(CXFA_Node* pFormNode);
   int32_t RemoveBindItem(CXFA_Node* pFormNode);
   bool HasBindItem() const;
@@ -442,7 +448,7 @@
   float GetHeightWithoutMargin(float fHeightCalc) const;
   void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF* pSize);
   CFX_SizeF CalculateAccWidthAndHeight(CXFA_FFDoc* doc, float fWidth);
-  void InitLayoutData();
+  void InitLayoutData(CXFA_FFDoc* doc);
   void StartTextLayout(CXFA_FFDoc* doc, float* pCalcWidth, float* pCalcHeight);
 
   void InsertListTextItem(CXFA_Node* pItems,
@@ -484,6 +490,10 @@
 
   CFX_XMLDocument* GetXMLDocument() const;
 
+  XFA_FFWidgetType ff_widget_type_ = XFA_FFWidgetType::kNone;
+  bool m_bIsNull = true;
+  bool m_bPreNull = true;
+  bool is_widget_ready_ = false;
   const pdfium::span<const PropertyData> m_Properties;
   const pdfium::span<const AttributeData> m_Attributes;
   const uint32_t m_ValidPackets;
@@ -492,14 +502,10 @@
   uint8_t m_ExecuteRecursionDepth = 0;
   uint16_t m_uNodeFlags = XFA_NodeFlag_None;
   uint32_t m_dwNameHash = 0;
-  CXFA_Node* m_pAuxNode = nullptr;         // Raw, node tree cleanup order.
-  std::vector<CXFA_Node*> binding_nodes_;  // Raw, node tree cleanup order.
-  bool m_bIsNull = true;
-  bool m_bPreNull = true;
-  bool is_widget_ready_ = false;
-  std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
-  CXFA_Ui* ui_ = nullptr;
-  XFA_FFWidgetType ff_widget_type_ = XFA_FFWidgetType::kNone;
+  cppgc::Member<CXFA_Node> m_pAuxNode;
+  std::vector<cppgc::Member<CXFA_Node>> binding_nodes_;
+  cppgc::Member<CXFA_WidgetLayoutData> m_pLayoutData;
+  cppgc::Member<CXFA_Ui> ui_;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NODE_H_
diff --git a/xfa/fxfa/parser/cxfa_node_unittest.cpp b/xfa/fxfa/parser/cxfa_node_unittest.cpp
index a085d24..7bf4171 100644
--- a/xfa/fxfa/parser/cxfa_node_unittest.cpp
+++ b/xfa/fxfa/parser/cxfa_node_unittest.cpp
@@ -4,14 +4,22 @@
 
 #include "xfa/fxfa/parser/cxfa_node.h"
 
+#include "fxjs/gc/heap.h"
 #include "fxjs/xfa/cjx_node.h"
+#include "testing/fxgc_unittest.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 
 namespace {
 
 class TestNode final : public CXFA_Node {
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+  ~TestNode() override = default;
+
+ private:
   explicit TestNode(CXFA_Document* doc)
       : CXFA_Node(doc,
                   XFA_PacketType::Form,
@@ -21,30 +29,32 @@
                   {},
                   {},
                   std::make_unique<CJX_Node>(this)) {}
-
-  ~TestNode() override = default;
 };
 
 }  // namespace
 
-class CXFANodeTest : public testing::Test {
+class CXFANodeTest : public FXGCUnitTest {
  public:
   void SetUp() override {
-    doc_ = std::make_unique<CXFA_Document>(nullptr, nullptr);
-    node_ = std::make_unique<TestNode>(doc_.get());
+    FXGCUnitTest::SetUp();
+    doc_ = cppgc::MakeGarbageCollected<CXFA_Document>(
+        heap()->GetAllocationHandle(), nullptr, heap(), nullptr);
+    node_ = cppgc::MakeGarbageCollected<TestNode>(heap()->GetAllocationHandle(),
+                                                  doc_);
   }
 
   void TearDown() override {
-    node_ = nullptr;
-    doc_ = nullptr;
+    node_.Clear();
+    doc_.Clear();
+    FXGCUnitTest::TearDown();
   }
 
-  CXFA_Document* GetDoc() const { return doc_.get(); }
-  CXFA_Node* GetNode() const { return node_.get(); }
+  CXFA_Document* GetDoc() const { return doc_; }
+  CXFA_Node* GetNode() const { return node_; }
 
  private:
-  std::unique_ptr<CXFA_Document> doc_;
-  std::unique_ptr<TestNode> node_;
+  cppgc::Persistent<CXFA_Document> doc_;
+  cppgc::Persistent<TestNode> node_;
 };
 
 TEST_F(CXFANodeTest, InsertFirstChild) {
diff --git a/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h b/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
index 7887d86..e1e0197 100644
--- a/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
+++ b/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
@@ -8,11 +8,14 @@
 #define XFA_FXFA_PARSER_CXFA_NODEITERATORTEMPLATE_H_
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/macros.h"
 
 template <class NodeType,
           class TraverseStrategy,
           typename HolderType = UnownedPtr<NodeType>>
 class CXFA_NodeIteratorTemplate {
+  CPPGC_STACK_ALLOCATED();  // Allows Raw/Unowned |HolderType|.
+
  public:
   explicit CXFA_NodeIteratorTemplate(NodeType* pRoot)
       : m_pRoot(pRoot), m_pCurrent(pRoot) {}
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.cpp b/xfa/fxfa/parser/cxfa_nodeowner.cpp
index 0cae85f..1126db4 100644
--- a/xfa/fxfa/parser/cxfa_nodeowner.cpp
+++ b/xfa/fxfa/parser/cxfa_nodeowner.cpp
@@ -15,18 +15,12 @@
 
 CXFA_NodeOwner::~CXFA_NodeOwner() = default;
 
-CXFA_Node* CXFA_NodeOwner::AddOwnedNode(std::unique_ptr<CXFA_Node> node) {
-  if (!node)
-    return nullptr;
-
-  CXFA_Node* ret = node.get();
-  nodes_.push_back(std::move(node));
-  return ret;
+void CXFA_NodeOwner::Trace(cppgc::Visitor* visitor) const {
+  for (const auto& list : lists_)
+    visitor->Trace(list);
 }
 
-CXFA_List* CXFA_NodeOwner::AddOwnedList(std::unique_ptr<CXFA_List> list) {
+void CXFA_NodeOwner::PersistList(CXFA_List* list) {
   ASSERT(list);
-  CXFA_List* ret = list.get();
-  lists_.push_back(std::move(list));
-  return ret;
+  lists_.emplace_back(list);
 }
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.h b/xfa/fxfa/parser/cxfa_nodeowner.h
index efba10f..6cfc538 100644
--- a/xfa/fxfa/parser/cxfa_nodeowner.h
+++ b/xfa/fxfa/parser/cxfa_nodeowner.h
@@ -7,27 +7,27 @@
 #ifndef XFA_FXFA_PARSER_CXFA_NODEOWNER_H_
 #define XFA_FXFA_PARSER_CXFA_NODEOWNER_H_
 
-#include <memory>
 #include <vector>
 
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
+
 class CXFA_List;
-class CXFA_Node;
 
-class CXFA_NodeOwner {
+class CXFA_NodeOwner : public cppgc::GarbageCollected<CXFA_NodeOwner> {
  public:
-  virtual ~CXFA_NodeOwner();
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+  ~CXFA_NodeOwner();
 
-  // Takes ownership of |node|, returns unowned pointer to it.
-  CXFA_Node* AddOwnedNode(std::unique_ptr<CXFA_Node> node);
+  void Trace(cppgc::Visitor* visitor) const;
+  void PersistList(CXFA_List* list);
 
-  // Takes ownership of |list|, returns unowned pointer to it.
-  CXFA_List* AddOwnedList(std::unique_ptr<CXFA_List> list);
-
- protected:
+ private:
   CXFA_NodeOwner();
 
-  std::vector<std::unique_ptr<CXFA_Node>> nodes_;  // Must outlive |lists_|.
-  std::vector<std::unique_ptr<CXFA_List>> lists_;
+  std::vector<cppgc::Member<CXFA_List>> lists_;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NODEOWNER_H_
diff --git a/xfa/fxfa/parser/cxfa_numberofcopies.h b/xfa/fxfa/parser/cxfa_numberofcopies.h
index 3215bb3..6720fe8 100644
--- a/xfa/fxfa/parser/cxfa_numberofcopies.h
+++ b/xfa/fxfa/parser/cxfa_numberofcopies.h
@@ -11,8 +11,11 @@
 
 class CXFA_NumberOfCopies final : public CXFA_Node {
  public:
-  CXFA_NumberOfCopies(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumberOfCopies() override;
+
+ private:
+  CXFA_NumberOfCopies(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMBEROFCOPIES_H_
diff --git a/xfa/fxfa/parser/cxfa_numberpattern.h b/xfa/fxfa/parser/cxfa_numberpattern.h
index 5c42d46..ad4737b 100644
--- a/xfa/fxfa/parser/cxfa_numberpattern.h
+++ b/xfa/fxfa/parser/cxfa_numberpattern.h
@@ -11,8 +11,11 @@
 
 class CXFA_NumberPattern final : public CXFA_Node {
  public:
-  CXFA_NumberPattern(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumberPattern() override;
+
+ private:
+  CXFA_NumberPattern(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMBERPATTERN_H_
diff --git a/xfa/fxfa/parser/cxfa_numberpatterns.h b/xfa/fxfa/parser/cxfa_numberpatterns.h
index 58c8cb6..d7f73b2 100644
--- a/xfa/fxfa/parser/cxfa_numberpatterns.h
+++ b/xfa/fxfa/parser/cxfa_numberpatterns.h
@@ -11,8 +11,11 @@
 
 class CXFA_NumberPatterns final : public CXFA_Node {
  public:
-  CXFA_NumberPatterns(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumberPatterns() override;
+
+ private:
+  CXFA_NumberPatterns(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMBERPATTERNS_H_
diff --git a/xfa/fxfa/parser/cxfa_numbersymbol.h b/xfa/fxfa/parser/cxfa_numbersymbol.h
index 404f366..dbdf2e7 100644
--- a/xfa/fxfa/parser/cxfa_numbersymbol.h
+++ b/xfa/fxfa/parser/cxfa_numbersymbol.h
@@ -11,8 +11,11 @@
 
 class CXFA_NumberSymbol final : public CXFA_Node {
  public:
-  CXFA_NumberSymbol(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumberSymbol() override;
+
+ private:
+  CXFA_NumberSymbol(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMBERSYMBOL_H_
diff --git a/xfa/fxfa/parser/cxfa_numbersymbols.h b/xfa/fxfa/parser/cxfa_numbersymbols.h
index 37bb6fc..8094047 100644
--- a/xfa/fxfa/parser/cxfa_numbersymbols.h
+++ b/xfa/fxfa/parser/cxfa_numbersymbols.h
@@ -11,8 +11,11 @@
 
 class CXFA_NumberSymbols final : public CXFA_Node {
  public:
-  CXFA_NumberSymbols(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumberSymbols() override;
+
+ private:
+  CXFA_NumberSymbols(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMBERSYMBOLS_H_
diff --git a/xfa/fxfa/parser/cxfa_numericedit.h b/xfa/fxfa/parser/cxfa_numericedit.h
index 145bf08..19a70fb 100644
--- a/xfa/fxfa/parser/cxfa_numericedit.h
+++ b/xfa/fxfa/parser/cxfa_numericedit.h
@@ -11,11 +11,14 @@
 
 class CXFA_NumericEdit final : public CXFA_Node {
  public:
-  CXFA_NumericEdit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_NumericEdit() override;
 
   XFA_Element GetValueNodeType() const override;
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_NumericEdit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NUMERICEDIT_H_
diff --git a/xfa/fxfa/parser/cxfa_object.cpp b/xfa/fxfa/parser/cxfa_object.cpp
index 272e82b..3c36aed 100644
--- a/xfa/fxfa/parser/cxfa_object.cpp
+++ b/xfa/fxfa/parser/cxfa_object.cpp
@@ -32,6 +32,10 @@
 
 CXFA_Object::~CXFA_Object() = default;
 
+void CXFA_Object::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pDocument);
+}
+
 WideString CXFA_Object::GetSOMExpression() {
   CXFA_Node* pNode = AsNode();
   return pNode ? pNode->GetNameExpression() : WideString();
diff --git a/xfa/fxfa/parser/cxfa_object.h b/xfa/fxfa/parser/cxfa_object.h
index 18bcb77..176bf89 100644
--- a/xfa/fxfa/parser/cxfa_object.h
+++ b/xfa/fxfa/parser/cxfa_object.h
@@ -10,9 +10,16 @@
 #include <memory>
 
 #include "core/fxcrt/fx_string.h"
+#include "fxjs/gc/heap.h"
 #include "fxjs/xfa/fxjse.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
+namespace cppgc {
+class Visitor;
+}  // namespace cppgc
+
 enum class XFA_ObjectType {
   Object,
   List,
@@ -34,10 +41,12 @@
 class CXFA_ThisProxy;
 class CXFA_TreeList;
 
-class CXFA_Object {
+class CXFA_Object : public cppgc::GarbageCollected<CXFA_Object> {
  public:
   virtual ~CXFA_Object();
 
+  virtual void Trace(cppgc::Visitor* visitor) const;
+
   CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
   XFA_ObjectType GetObjectType() const { return m_objectType; }
 
@@ -92,7 +101,7 @@
               XFA_Element eType,
               std::unique_ptr<CJX_Object> jsObject);
 
-  UnownedPtr<CXFA_Document> const m_pDocument;
+  cppgc::WeakMember<CXFA_Document> m_pDocument;
   const XFA_ObjectType m_objectType;
   const XFA_Element m_elementType;
   const ByteStringView m_elementName;
diff --git a/xfa/fxfa/parser/cxfa_occur.h b/xfa/fxfa/parser/cxfa_occur.h
index 58029a3..c1298d4 100644
--- a/xfa/fxfa/parser/cxfa_occur.h
+++ b/xfa/fxfa/parser/cxfa_occur.h
@@ -16,7 +16,7 @@
   static constexpr int32_t kDefaultMax = 1;
   static constexpr int32_t kDefaultMin = 1;
 
-  CXFA_Occur(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Occur() override;
 
   int32_t GetMax();
@@ -26,6 +26,9 @@
   void SetMin(int32_t iMin);
 
   std::tuple<int32_t, int32_t, int32_t> GetOccurInfo();
+
+ private:
+  CXFA_Occur(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OCCUR_H_
diff --git a/xfa/fxfa/parser/cxfa_oid.h b/xfa/fxfa/parser/cxfa_oid.h
index c9ccb71..d99754f 100644
--- a/xfa/fxfa/parser/cxfa_oid.h
+++ b/xfa/fxfa/parser/cxfa_oid.h
@@ -11,8 +11,11 @@
 
 class CXFA_Oid final : public CXFA_Node {
  public:
-  CXFA_Oid(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Oid() override;
+
+ private:
+  CXFA_Oid(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OID_H_
diff --git a/xfa/fxfa/parser/cxfa_oids.h b/xfa/fxfa/parser/cxfa_oids.h
index f537601..af617ff 100644
--- a/xfa/fxfa/parser/cxfa_oids.h
+++ b/xfa/fxfa/parser/cxfa_oids.h
@@ -11,8 +11,11 @@
 
 class CXFA_Oids final : public CXFA_Node {
  public:
-  CXFA_Oids(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Oids() override;
+
+ private:
+  CXFA_Oids(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OIDS_H_
diff --git a/xfa/fxfa/parser/cxfa_openaction.h b/xfa/fxfa/parser/cxfa_openaction.h
index 2eff67c..f19e538 100644
--- a/xfa/fxfa/parser/cxfa_openaction.h
+++ b/xfa/fxfa/parser/cxfa_openaction.h
@@ -11,8 +11,11 @@
 
 class CXFA_OpenAction final : public CXFA_Node {
  public:
-  CXFA_OpenAction(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_OpenAction() override;
+
+ private:
+  CXFA_OpenAction(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OPENACTION_H_
diff --git a/xfa/fxfa/parser/cxfa_operation.h b/xfa/fxfa/parser/cxfa_operation.h
index 4df63aa..ee1247f 100644
--- a/xfa/fxfa/parser/cxfa_operation.h
+++ b/xfa/fxfa/parser/cxfa_operation.h
@@ -11,8 +11,11 @@
 
 class CXFA_Operation final : public CXFA_Node {
  public:
-  CXFA_Operation(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Operation() override;
+
+ private:
+  CXFA_Operation(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OPERATION_H_
diff --git a/xfa/fxfa/parser/cxfa_output.h b/xfa/fxfa/parser/cxfa_output.h
index 45555be..a8b5cbd 100644
--- a/xfa/fxfa/parser/cxfa_output.h
+++ b/xfa/fxfa/parser/cxfa_output.h
@@ -11,8 +11,11 @@
 
 class CXFA_Output final : public CXFA_Node {
  public:
-  CXFA_Output(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Output() override;
+
+ private:
+  CXFA_Output(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OUTPUT_H_
diff --git a/xfa/fxfa/parser/cxfa_outputbin.h b/xfa/fxfa/parser/cxfa_outputbin.h
index 7ab4540..f8387ab 100644
--- a/xfa/fxfa/parser/cxfa_outputbin.h
+++ b/xfa/fxfa/parser/cxfa_outputbin.h
@@ -11,8 +11,11 @@
 
 class CXFA_OutputBin final : public CXFA_Node {
  public:
-  CXFA_OutputBin(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_OutputBin() override;
+
+ private:
+  CXFA_OutputBin(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OUTPUTBIN_H_
diff --git a/xfa/fxfa/parser/cxfa_outputxsl.h b/xfa/fxfa/parser/cxfa_outputxsl.h
index 361ea42..5d448e1 100644
--- a/xfa/fxfa/parser/cxfa_outputxsl.h
+++ b/xfa/fxfa/parser/cxfa_outputxsl.h
@@ -11,8 +11,11 @@
 
 class CXFA_OutputXSL final : public CXFA_Node {
  public:
-  CXFA_OutputXSL(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_OutputXSL() override;
+
+ private:
+  CXFA_OutputXSL(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OUTPUTXSL_H_
diff --git a/xfa/fxfa/parser/cxfa_overflow.h b/xfa/fxfa/parser/cxfa_overflow.h
index da2717a..aa8c2be 100644
--- a/xfa/fxfa/parser/cxfa_overflow.h
+++ b/xfa/fxfa/parser/cxfa_overflow.h
@@ -11,8 +11,11 @@
 
 class CXFA_Overflow final : public CXFA_Node {
  public:
-  CXFA_Overflow(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Overflow() override;
+
+ private:
+  CXFA_Overflow(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OVERFLOW_H_
diff --git a/xfa/fxfa/parser/cxfa_overprint.h b/xfa/fxfa/parser/cxfa_overprint.h
index e5e360d..17b8895 100644
--- a/xfa/fxfa/parser/cxfa_overprint.h
+++ b/xfa/fxfa/parser/cxfa_overprint.h
@@ -11,8 +11,11 @@
 
 class CXFA_Overprint final : public CXFA_Node {
  public:
-  CXFA_Overprint(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Overprint() override;
+
+ private:
+  CXFA_Overprint(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_OVERPRINT_H_
diff --git a/xfa/fxfa/parser/cxfa_packet.h b/xfa/fxfa/parser/cxfa_packet.h
index c94c74c..dccecbc 100644
--- a/xfa/fxfa/parser/cxfa_packet.h
+++ b/xfa/fxfa/parser/cxfa_packet.h
@@ -11,8 +11,11 @@
 
 class CXFA_Packet final : public CXFA_Node {
  public:
-  CXFA_Packet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Packet() override;
+
+ private:
+  CXFA_Packet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PACKET_H_
diff --git a/xfa/fxfa/parser/cxfa_packets.h b/xfa/fxfa/parser/cxfa_packets.h
index 5e0f408..dd4fd37 100644
--- a/xfa/fxfa/parser/cxfa_packets.h
+++ b/xfa/fxfa/parser/cxfa_packets.h
@@ -11,8 +11,11 @@
 
 class CXFA_Packets final : public CXFA_Node {
  public:
-  CXFA_Packets(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Packets() override;
+
+ private:
+  CXFA_Packets(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PACKETS_H_
diff --git a/xfa/fxfa/parser/cxfa_pagearea.h b/xfa/fxfa/parser/cxfa_pagearea.h
index 8a8afaa..c0006f7 100644
--- a/xfa/fxfa/parser/cxfa_pagearea.h
+++ b/xfa/fxfa/parser/cxfa_pagearea.h
@@ -11,8 +11,11 @@
 
 class CXFA_PageArea final : public CXFA_Node {
  public:
-  CXFA_PageArea(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PageArea() override;
+
+ private:
+  CXFA_PageArea(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGEAREA_H_
diff --git a/xfa/fxfa/parser/cxfa_pageoffset.h b/xfa/fxfa/parser/cxfa_pageoffset.h
index d090b11..a3706a5 100644
--- a/xfa/fxfa/parser/cxfa_pageoffset.h
+++ b/xfa/fxfa/parser/cxfa_pageoffset.h
@@ -11,8 +11,11 @@
 
 class CXFA_PageOffset final : public CXFA_Node {
  public:
-  CXFA_PageOffset(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PageOffset() override;
+
+ private:
+  CXFA_PageOffset(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGEOFFSET_H_
diff --git a/xfa/fxfa/parser/cxfa_pagerange.h b/xfa/fxfa/parser/cxfa_pagerange.h
index a0317b5..c362e7f 100644
--- a/xfa/fxfa/parser/cxfa_pagerange.h
+++ b/xfa/fxfa/parser/cxfa_pagerange.h
@@ -11,8 +11,11 @@
 
 class CXFA_PageRange final : public CXFA_Node {
  public:
-  CXFA_PageRange(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PageRange() override;
+
+ private:
+  CXFA_PageRange(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGERANGE_H_
diff --git a/xfa/fxfa/parser/cxfa_pageset.h b/xfa/fxfa/parser/cxfa_pageset.h
index da71581..02d9626 100644
--- a/xfa/fxfa/parser/cxfa_pageset.h
+++ b/xfa/fxfa/parser/cxfa_pageset.h
@@ -11,8 +11,11 @@
 
 class CXFA_PageSet final : public CXFA_Node {
  public:
-  CXFA_PageSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PageSet() override;
+
+ private:
+  CXFA_PageSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGESET_H_
diff --git a/xfa/fxfa/parser/cxfa_pagination.h b/xfa/fxfa/parser/cxfa_pagination.h
index 9bbd820..70ece45 100644
--- a/xfa/fxfa/parser/cxfa_pagination.h
+++ b/xfa/fxfa/parser/cxfa_pagination.h
@@ -11,8 +11,11 @@
 
 class CXFA_Pagination final : public CXFA_Node {
  public:
-  CXFA_Pagination(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Pagination() override;
+
+ private:
+  CXFA_Pagination(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGINATION_H_
diff --git a/xfa/fxfa/parser/cxfa_paginationoverride.h b/xfa/fxfa/parser/cxfa_paginationoverride.h
index 4f0efba..b22bc3c 100644
--- a/xfa/fxfa/parser/cxfa_paginationoverride.h
+++ b/xfa/fxfa/parser/cxfa_paginationoverride.h
@@ -11,8 +11,11 @@
 
 class CXFA_PaginationOverride final : public CXFA_Node {
  public:
-  CXFA_PaginationOverride(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PaginationOverride() override;
+
+ private:
+  CXFA_PaginationOverride(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PAGINATIONOVERRIDE_H_
diff --git a/xfa/fxfa/parser/cxfa_para.h b/xfa/fxfa/parser/cxfa_para.h
index 735a199..08a9c6e 100644
--- a/xfa/fxfa/parser/cxfa_para.h
+++ b/xfa/fxfa/parser/cxfa_para.h
@@ -11,7 +11,7 @@
 
 class CXFA_Para final : public CXFA_Node {
  public:
-  CXFA_Para(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Para() override;
 
   XFA_AttributeValue GetHorizontalAlign();
@@ -22,6 +22,9 @@
   float GetSpaceAbove();
   float GetSpaceBelow();
   float GetTextIndent();
+
+ private:
+  CXFA_Para(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PARA_H_
diff --git a/xfa/fxfa/parser/cxfa_part.h b/xfa/fxfa/parser/cxfa_part.h
index 99c2c59..14018df 100644
--- a/xfa/fxfa/parser/cxfa_part.h
+++ b/xfa/fxfa/parser/cxfa_part.h
@@ -11,8 +11,11 @@
 
 class CXFA_Part final : public CXFA_Node {
  public:
-  CXFA_Part(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Part() override;
+
+ private:
+  CXFA_Part(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PART_H_
diff --git a/xfa/fxfa/parser/cxfa_password.h b/xfa/fxfa/parser/cxfa_password.h
index a2cbca7..6c6e833 100644
--- a/xfa/fxfa/parser/cxfa_password.h
+++ b/xfa/fxfa/parser/cxfa_password.h
@@ -11,8 +11,11 @@
 
 class CXFA_Password final : public CXFA_Node {
  public:
-  CXFA_Password(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Password() override;
+
+ private:
+  CXFA_Password(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PASSWORD_H_
diff --git a/xfa/fxfa/parser/cxfa_passwordedit.h b/xfa/fxfa/parser/cxfa_passwordedit.h
index fae812f..4ac090c 100644
--- a/xfa/fxfa/parser/cxfa_passwordedit.h
+++ b/xfa/fxfa/parser/cxfa_passwordedit.h
@@ -11,11 +11,14 @@
 
 class CXFA_PasswordEdit final : public CXFA_Node {
  public:
-  CXFA_PasswordEdit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PasswordEdit() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
   WideString GetPasswordChar();
+
+ private:
+  CXFA_PasswordEdit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PASSWORDEDIT_H_
diff --git a/xfa/fxfa/parser/cxfa_pattern.h b/xfa/fxfa/parser/cxfa_pattern.h
index bf5c526..87c6c23 100644
--- a/xfa/fxfa/parser/cxfa_pattern.h
+++ b/xfa/fxfa/parser/cxfa_pattern.h
@@ -19,7 +19,7 @@
   static constexpr XFA_AttributeValue kDefaultType =
       XFA_AttributeValue::Unknown;
 
-  CXFA_Pattern(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Pattern() override;
 
   void Draw(CXFA_Graphics* pGS,
@@ -29,6 +29,8 @@
             const CFX_Matrix& matrix);
 
  private:
+  CXFA_Pattern(CXFA_Document* doc, XFA_PacketType packet);
+
   XFA_AttributeValue GetType();
   CXFA_Color* GetColorIfExists();
 };
diff --git a/xfa/fxfa/parser/cxfa_pcl.h b/xfa/fxfa/parser/cxfa_pcl.h
index c9d94d6..ddb189a 100644
--- a/xfa/fxfa/parser/cxfa_pcl.h
+++ b/xfa/fxfa/parser/cxfa_pcl.h
@@ -11,8 +11,11 @@
 
 class CXFA_Pcl final : public CXFA_Node {
  public:
-  CXFA_Pcl(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Pcl() override;
+
+ private:
+  CXFA_Pcl(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PCL_H_
diff --git a/xfa/fxfa/parser/cxfa_pdf.h b/xfa/fxfa/parser/cxfa_pdf.h
index 00e4d38..c469cd3 100644
--- a/xfa/fxfa/parser/cxfa_pdf.h
+++ b/xfa/fxfa/parser/cxfa_pdf.h
@@ -11,8 +11,11 @@
 
 class CXFA_Pdf final : public CXFA_Node {
  public:
-  CXFA_Pdf(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Pdf() override;
+
+ private:
+  CXFA_Pdf(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PDF_H_
diff --git a/xfa/fxfa/parser/cxfa_pdfa.h b/xfa/fxfa/parser/cxfa_pdfa.h
index e43f025..cc3442f 100644
--- a/xfa/fxfa/parser/cxfa_pdfa.h
+++ b/xfa/fxfa/parser/cxfa_pdfa.h
@@ -11,8 +11,11 @@
 
 class CXFA_Pdfa final : public CXFA_Node {
  public:
-  CXFA_Pdfa(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Pdfa() override;
+
+ private:
+  CXFA_Pdfa(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PDFA_H_
diff --git a/xfa/fxfa/parser/cxfa_permissions.h b/xfa/fxfa/parser/cxfa_permissions.h
index 79b3bf1..5089af1 100644
--- a/xfa/fxfa/parser/cxfa_permissions.h
+++ b/xfa/fxfa/parser/cxfa_permissions.h
@@ -11,8 +11,11 @@
 
 class CXFA_Permissions final : public CXFA_Node {
  public:
-  CXFA_Permissions(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Permissions() override;
+
+ private:
+  CXFA_Permissions(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PERMISSIONS_H_
diff --git a/xfa/fxfa/parser/cxfa_picktraybypdfsize.h b/xfa/fxfa/parser/cxfa_picktraybypdfsize.h
index 3871552..654262f 100644
--- a/xfa/fxfa/parser/cxfa_picktraybypdfsize.h
+++ b/xfa/fxfa/parser/cxfa_picktraybypdfsize.h
@@ -11,8 +11,11 @@
 
 class CXFA_PickTrayByPDFSize final : public CXFA_Node {
  public:
-  CXFA_PickTrayByPDFSize(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PickTrayByPDFSize() override;
+
+ private:
+  CXFA_PickTrayByPDFSize(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PICKTRAYBYPDFSIZE_H_
diff --git a/xfa/fxfa/parser/cxfa_picture.h b/xfa/fxfa/parser/cxfa_picture.h
index 304c7b9..ee457cb 100644
--- a/xfa/fxfa/parser/cxfa_picture.h
+++ b/xfa/fxfa/parser/cxfa_picture.h
@@ -11,8 +11,11 @@
 
 class CXFA_Picture final : public CXFA_Node {
  public:
-  CXFA_Picture(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Picture() override;
+
+ private:
+  CXFA_Picture(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PICTURE_H_
diff --git a/xfa/fxfa/parser/cxfa_plaintextmetadata.h b/xfa/fxfa/parser/cxfa_plaintextmetadata.h
index 65e0ded..d0638b5 100644
--- a/xfa/fxfa/parser/cxfa_plaintextmetadata.h
+++ b/xfa/fxfa/parser/cxfa_plaintextmetadata.h
@@ -11,8 +11,11 @@
 
 class CXFA_PlaintextMetadata final : public CXFA_Node {
  public:
-  CXFA_PlaintextMetadata(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PlaintextMetadata() override;
+
+ private:
+  CXFA_PlaintextMetadata(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PLAINTEXTMETADATA_H_
diff --git a/xfa/fxfa/parser/cxfa_presence.h b/xfa/fxfa/parser/cxfa_presence.h
index 1bd6e45..c5498af 100644
--- a/xfa/fxfa/parser/cxfa_presence.h
+++ b/xfa/fxfa/parser/cxfa_presence.h
@@ -11,8 +11,11 @@
 
 class CXFA_Presence final : public CXFA_Node {
  public:
-  CXFA_Presence(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Presence() override;
+
+ private:
+  CXFA_Presence(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRESENCE_H_
diff --git a/xfa/fxfa/parser/cxfa_present.h b/xfa/fxfa/parser/cxfa_present.h
index 36db503..3dce649 100644
--- a/xfa/fxfa/parser/cxfa_present.h
+++ b/xfa/fxfa/parser/cxfa_present.h
@@ -11,8 +11,11 @@
 
 class CXFA_Present final : public CXFA_Node {
  public:
-  CXFA_Present(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Present() override;
+
+ private:
+  CXFA_Present(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRESENT_H_
diff --git a/xfa/fxfa/parser/cxfa_print.h b/xfa/fxfa/parser/cxfa_print.h
index 7f6fff9..ba98ead 100644
--- a/xfa/fxfa/parser/cxfa_print.h
+++ b/xfa/fxfa/parser/cxfa_print.h
@@ -11,8 +11,11 @@
 
 class CXFA_Print final : public CXFA_Node {
  public:
-  CXFA_Print(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Print() override;
+
+ private:
+  CXFA_Print(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRINT_H_
diff --git a/xfa/fxfa/parser/cxfa_printername.h b/xfa/fxfa/parser/cxfa_printername.h
index a85d61e..69fda73 100644
--- a/xfa/fxfa/parser/cxfa_printername.h
+++ b/xfa/fxfa/parser/cxfa_printername.h
@@ -11,8 +11,11 @@
 
 class CXFA_PrinterName final : public CXFA_Node {
  public:
-  CXFA_PrinterName(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PrinterName() override;
+
+ private:
+  CXFA_PrinterName(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRINTERNAME_H_
diff --git a/xfa/fxfa/parser/cxfa_printhighquality.h b/xfa/fxfa/parser/cxfa_printhighquality.h
index 6268489..5c0ba08 100644
--- a/xfa/fxfa/parser/cxfa_printhighquality.h
+++ b/xfa/fxfa/parser/cxfa_printhighquality.h
@@ -11,8 +11,11 @@
 
 class CXFA_PrintHighQuality final : public CXFA_Node {
  public:
-  CXFA_PrintHighQuality(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PrintHighQuality() override;
+
+ private:
+  CXFA_PrintHighQuality(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRINTHIGHQUALITY_H_
diff --git a/xfa/fxfa/parser/cxfa_printscaling.h b/xfa/fxfa/parser/cxfa_printscaling.h
index 76bf112..1a04427 100644
--- a/xfa/fxfa/parser/cxfa_printscaling.h
+++ b/xfa/fxfa/parser/cxfa_printscaling.h
@@ -11,8 +11,11 @@
 
 class CXFA_PrintScaling final : public CXFA_Node {
  public:
-  CXFA_PrintScaling(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PrintScaling() override;
+
+ private:
+  CXFA_PrintScaling(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRINTSCALING_H_
diff --git a/xfa/fxfa/parser/cxfa_producer.h b/xfa/fxfa/parser/cxfa_producer.h
index c40a334..78379fe 100644
--- a/xfa/fxfa/parser/cxfa_producer.h
+++ b/xfa/fxfa/parser/cxfa_producer.h
@@ -11,8 +11,11 @@
 
 class CXFA_Producer final : public CXFA_Node {
  public:
-  CXFA_Producer(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Producer() override;
+
+ private:
+  CXFA_Producer(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PRODUCER_H_
diff --git a/xfa/fxfa/parser/cxfa_proto.h b/xfa/fxfa/parser/cxfa_proto.h
index 5af7ba2..9ee72cb 100644
--- a/xfa/fxfa/parser/cxfa_proto.h
+++ b/xfa/fxfa/parser/cxfa_proto.h
@@ -11,8 +11,11 @@
 
 class CXFA_Proto final : public CXFA_Node {
  public:
-  CXFA_Proto(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Proto() override;
+
+ private:
+  CXFA_Proto(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PROTO_H_
diff --git a/xfa/fxfa/parser/cxfa_ps.h b/xfa/fxfa/parser/cxfa_ps.h
index f51c510..60dddd7 100644
--- a/xfa/fxfa/parser/cxfa_ps.h
+++ b/xfa/fxfa/parser/cxfa_ps.h
@@ -11,8 +11,11 @@
 
 class CXFA_Ps final : public CXFA_Node {
  public:
-  CXFA_Ps(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Ps() override;
+
+ private:
+  CXFA_Ps(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PS_H_
diff --git a/xfa/fxfa/parser/cxfa_psmap.h b/xfa/fxfa/parser/cxfa_psmap.h
index 802e123..bb757c9 100644
--- a/xfa/fxfa/parser/cxfa_psmap.h
+++ b/xfa/fxfa/parser/cxfa_psmap.h
@@ -11,8 +11,11 @@
 
 class CXFA_PsMap final : public CXFA_Node {
  public:
-  CXFA_PsMap(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_PsMap() override;
+
+ private:
+  CXFA_PsMap(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_PSMAP_H_
diff --git a/xfa/fxfa/parser/cxfa_query.h b/xfa/fxfa/parser/cxfa_query.h
index 7d62c68..3c85206 100644
--- a/xfa/fxfa/parser/cxfa_query.h
+++ b/xfa/fxfa/parser/cxfa_query.h
@@ -11,8 +11,11 @@
 
 class CXFA_Query final : public CXFA_Node {
  public:
-  CXFA_Query(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Query() override;
+
+ private:
+  CXFA_Query(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_QUERY_H_
diff --git a/xfa/fxfa/parser/cxfa_radial.h b/xfa/fxfa/parser/cxfa_radial.h
index 8fb30b5..4b4378c 100644
--- a/xfa/fxfa/parser/cxfa_radial.h
+++ b/xfa/fxfa/parser/cxfa_radial.h
@@ -16,7 +16,7 @@
 
 class CXFA_Radial final : public CXFA_Node {
  public:
-  CXFA_Radial(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Radial() override;
 
   void Draw(CXFA_Graphics* pGS,
@@ -26,6 +26,8 @@
             const CFX_Matrix& matrix);
 
  private:
+  CXFA_Radial(CXFA_Document* doc, XFA_PacketType packet);
+
   bool IsToEdge();
   CXFA_Color* GetColorIfExists();
 };
diff --git a/xfa/fxfa/parser/cxfa_range.h b/xfa/fxfa/parser/cxfa_range.h
index 5d8920d..e8e1d4b 100644
--- a/xfa/fxfa/parser/cxfa_range.h
+++ b/xfa/fxfa/parser/cxfa_range.h
@@ -11,8 +11,11 @@
 
 class CXFA_Range final : public CXFA_Node {
  public:
-  CXFA_Range(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Range() override;
+
+ private:
+  CXFA_Range(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RANGE_H_
diff --git a/xfa/fxfa/parser/cxfa_reason.h b/xfa/fxfa/parser/cxfa_reason.h
index 1475637..1a5efec 100644
--- a/xfa/fxfa/parser/cxfa_reason.h
+++ b/xfa/fxfa/parser/cxfa_reason.h
@@ -11,8 +11,11 @@
 
 class CXFA_Reason final : public CXFA_Node {
  public:
-  CXFA_Reason(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Reason() override;
+
+ private:
+  CXFA_Reason(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_REASON_H_
diff --git a/xfa/fxfa/parser/cxfa_reasons.h b/xfa/fxfa/parser/cxfa_reasons.h
index 673a9b2..17c5846 100644
--- a/xfa/fxfa/parser/cxfa_reasons.h
+++ b/xfa/fxfa/parser/cxfa_reasons.h
@@ -11,8 +11,11 @@
 
 class CXFA_Reasons final : public CXFA_Node {
  public:
-  CXFA_Reasons(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Reasons() override;
+
+ private:
+  CXFA_Reasons(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_REASONS_H_
diff --git a/xfa/fxfa/parser/cxfa_record.h b/xfa/fxfa/parser/cxfa_record.h
index de0d0c4..e968fc1 100644
--- a/xfa/fxfa/parser/cxfa_record.h
+++ b/xfa/fxfa/parser/cxfa_record.h
@@ -11,8 +11,11 @@
 
 class CXFA_Record final : public CXFA_Node {
  public:
-  CXFA_Record(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Record() override;
+
+ private:
+  CXFA_Record(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RECORD_H_
diff --git a/xfa/fxfa/parser/cxfa_recordset.h b/xfa/fxfa/parser/cxfa_recordset.h
index a9895bd..d0fd36c 100644
--- a/xfa/fxfa/parser/cxfa_recordset.h
+++ b/xfa/fxfa/parser/cxfa_recordset.h
@@ -11,8 +11,11 @@
 
 class CXFA_RecordSet final : public CXFA_Node {
  public:
-  CXFA_RecordSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_RecordSet() override;
+
+ private:
+  CXFA_RecordSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RECORDSET_H_
diff --git a/xfa/fxfa/parser/cxfa_rectangle.h b/xfa/fxfa/parser/cxfa_rectangle.h
index 6d17471..7070f2e 100644
--- a/xfa/fxfa/parser/cxfa_rectangle.h
+++ b/xfa/fxfa/parser/cxfa_rectangle.h
@@ -15,7 +15,7 @@
 
 class CXFA_Rectangle : public CXFA_Box {
  public:
-  CXFA_Rectangle(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Rectangle() override;
 
   void GetFillPath(const std::vector<CXFA_Stroke*>& strokes,
@@ -27,6 +27,7 @@
             const CFX_Matrix& matrix);
 
  protected:
+  CXFA_Rectangle(CXFA_Document* doc, XFA_PacketType packet);
   CXFA_Rectangle(CXFA_Document* pDoc,
                  XFA_PacketType ePacket,
                  uint32_t validPackets,
@@ -36,7 +37,6 @@
                  pdfium::span<const AttributeData> attributes,
                  std::unique_ptr<CJX_Object> js_node);
 
- private:
   void Stroke(const std::vector<CXFA_Stroke*>& strokes,
               CXFA_Graphics* pGS,
               CFX_RectF rtWidget,
diff --git a/xfa/fxfa/parser/cxfa_ref.h b/xfa/fxfa/parser/cxfa_ref.h
index 5ab8e00..71503ab 100644
--- a/xfa/fxfa/parser/cxfa_ref.h
+++ b/xfa/fxfa/parser/cxfa_ref.h
@@ -11,8 +11,11 @@
 
 class CXFA_Ref final : public CXFA_Node {
  public:
-  CXFA_Ref(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Ref() override;
+
+ private:
+  CXFA_Ref(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_REF_H_
diff --git a/xfa/fxfa/parser/cxfa_relevant.h b/xfa/fxfa/parser/cxfa_relevant.h
index 03283c3..2b17606 100644
--- a/xfa/fxfa/parser/cxfa_relevant.h
+++ b/xfa/fxfa/parser/cxfa_relevant.h
@@ -11,8 +11,11 @@
 
 class CXFA_Relevant final : public CXFA_Node {
  public:
-  CXFA_Relevant(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Relevant() override;
+
+ private:
+  CXFA_Relevant(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RELEVANT_H_
diff --git a/xfa/fxfa/parser/cxfa_rename.h b/xfa/fxfa/parser/cxfa_rename.h
index f50d852..d5d4b5b 100644
--- a/xfa/fxfa/parser/cxfa_rename.h
+++ b/xfa/fxfa/parser/cxfa_rename.h
@@ -11,8 +11,11 @@
 
 class CXFA_Rename final : public CXFA_Node {
  public:
-  CXFA_Rename(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Rename() override;
+
+ private:
+  CXFA_Rename(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RENAME_H_
diff --git a/xfa/fxfa/parser/cxfa_renderpolicy.h b/xfa/fxfa/parser/cxfa_renderpolicy.h
index 4947289..5728a19 100644
--- a/xfa/fxfa/parser/cxfa_renderpolicy.h
+++ b/xfa/fxfa/parser/cxfa_renderpolicy.h
@@ -11,8 +11,11 @@
 
 class CXFA_RenderPolicy final : public CXFA_Node {
  public:
-  CXFA_RenderPolicy(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_RenderPolicy() override;
+
+ private:
+  CXFA_RenderPolicy(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RENDERPOLICY_H_
diff --git a/xfa/fxfa/parser/cxfa_rootelement.h b/xfa/fxfa/parser/cxfa_rootelement.h
index 4a9218e..c7fc70e 100644
--- a/xfa/fxfa/parser/cxfa_rootelement.h
+++ b/xfa/fxfa/parser/cxfa_rootelement.h
@@ -11,8 +11,11 @@
 
 class CXFA_RootElement final : public CXFA_Node {
  public:
-  CXFA_RootElement(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_RootElement() override;
+
+ private:
+  CXFA_RootElement(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ROOTELEMENT_H_
diff --git a/xfa/fxfa/parser/cxfa_runscripts.h b/xfa/fxfa/parser/cxfa_runscripts.h
index 2f80b0d..f46a0a9 100644
--- a/xfa/fxfa/parser/cxfa_runscripts.h
+++ b/xfa/fxfa/parser/cxfa_runscripts.h
@@ -11,8 +11,11 @@
 
 class CXFA_RunScripts final : public CXFA_Node {
  public:
-  CXFA_RunScripts(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_RunScripts() override;
+
+ private:
+  CXFA_RunScripts(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_RUNSCRIPTS_H_
diff --git a/xfa/fxfa/parser/cxfa_script.h b/xfa/fxfa/parser/cxfa_script.h
index f559284..065a400 100644
--- a/xfa/fxfa/parser/cxfa_script.h
+++ b/xfa/fxfa/parser/cxfa_script.h
@@ -18,12 +18,15 @@
     Unknown,
   };
 
-  CXFA_Script(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Script() override;
 
   Type GetContentType();
   XFA_AttributeValue GetRunAt();
   WideString GetExpression();
+
+ private:
+  CXFA_Script(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SCRIPT_H_
diff --git a/xfa/fxfa/parser/cxfa_scriptmodel.h b/xfa/fxfa/parser/cxfa_scriptmodel.h
index a71073e..93f7830 100644
--- a/xfa/fxfa/parser/cxfa_scriptmodel.h
+++ b/xfa/fxfa/parser/cxfa_scriptmodel.h
@@ -11,8 +11,11 @@
 
 class CXFA_ScriptModel final : public CXFA_Node {
  public:
-  CXFA_ScriptModel(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ScriptModel() override;
+
+ private:
+  CXFA_ScriptModel(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SCRIPTMODEL_H_
diff --git a/xfa/fxfa/parser/cxfa_select.h b/xfa/fxfa/parser/cxfa_select.h
index 82fc0d2..e36f635 100644
--- a/xfa/fxfa/parser/cxfa_select.h
+++ b/xfa/fxfa/parser/cxfa_select.h
@@ -11,8 +11,11 @@
 
 class CXFA_Select final : public CXFA_Node {
  public:
-  CXFA_Select(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Select() override;
+
+ private:
+  CXFA_Select(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SELECT_H_
diff --git a/xfa/fxfa/parser/cxfa_setproperty.h b/xfa/fxfa/parser/cxfa_setproperty.h
index aab588b..05ba91a 100644
--- a/xfa/fxfa/parser/cxfa_setproperty.h
+++ b/xfa/fxfa/parser/cxfa_setproperty.h
@@ -11,8 +11,11 @@
 
 class CXFA_SetProperty final : public CXFA_Node {
  public:
-  CXFA_SetProperty(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SetProperty() override;
+
+ private:
+  CXFA_SetProperty(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SETPROPERTY_H_
diff --git a/xfa/fxfa/parser/cxfa_severity.h b/xfa/fxfa/parser/cxfa_severity.h
index b2283c9..22e5a71 100644
--- a/xfa/fxfa/parser/cxfa_severity.h
+++ b/xfa/fxfa/parser/cxfa_severity.h
@@ -11,8 +11,11 @@
 
 class CXFA_Severity final : public CXFA_Node {
  public:
-  CXFA_Severity(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Severity() override;
+
+ private:
+  CXFA_Severity(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SEVERITY_H_
diff --git a/xfa/fxfa/parser/cxfa_sharptext.h b/xfa/fxfa/parser/cxfa_sharptext.h
index f2a41e8..d3af58e 100644
--- a/xfa/fxfa/parser/cxfa_sharptext.h
+++ b/xfa/fxfa/parser/cxfa_sharptext.h
@@ -11,8 +11,11 @@
 
 class CXFA_Sharptext final : public CXFA_Node {
  public:
-  CXFA_Sharptext(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Sharptext() override;
+
+ private:
+  CXFA_Sharptext(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SHARPTEXT_H_
diff --git a/xfa/fxfa/parser/cxfa_sharpxhtml.h b/xfa/fxfa/parser/cxfa_sharpxhtml.h
index b73789d..21411ee 100644
--- a/xfa/fxfa/parser/cxfa_sharpxhtml.h
+++ b/xfa/fxfa/parser/cxfa_sharpxhtml.h
@@ -11,8 +11,11 @@
 
 class CXFA_SharpxHTML final : public CXFA_Node {
  public:
-  CXFA_SharpxHTML(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SharpxHTML() override;
+
+ private:
+  CXFA_SharpxHTML(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SHARPXHTML_H_
diff --git a/xfa/fxfa/parser/cxfa_sharpxml.h b/xfa/fxfa/parser/cxfa_sharpxml.h
index b2e467a..050ec61 100644
--- a/xfa/fxfa/parser/cxfa_sharpxml.h
+++ b/xfa/fxfa/parser/cxfa_sharpxml.h
@@ -11,8 +11,11 @@
 
 class CXFA_Sharpxml final : public CXFA_Node {
  public:
-  CXFA_Sharpxml(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Sharpxml() override;
+
+ private:
+  CXFA_Sharpxml(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SHARPXML_H_
diff --git a/xfa/fxfa/parser/cxfa_signature.h b/xfa/fxfa/parser/cxfa_signature.h
index 678e892..2381201 100644
--- a/xfa/fxfa/parser/cxfa_signature.h
+++ b/xfa/fxfa/parser/cxfa_signature.h
@@ -11,10 +11,13 @@
 
 class CXFA_Signature final : public CXFA_Node {
  public:
-  CXFA_Signature(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Signature() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_Signature(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SIGNATURE_H_
diff --git a/xfa/fxfa/parser/cxfa_signatureproperties.h b/xfa/fxfa/parser/cxfa_signatureproperties.h
index a66346e..3a8aa00 100644
--- a/xfa/fxfa/parser/cxfa_signatureproperties.h
+++ b/xfa/fxfa/parser/cxfa_signatureproperties.h
@@ -11,8 +11,11 @@
 
 class CXFA_SignatureProperties final : public CXFA_Node {
  public:
-  CXFA_SignatureProperties(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SignatureProperties() override;
+
+ private:
+  CXFA_SignatureProperties(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SIGNATUREPROPERTIES_H_
diff --git a/xfa/fxfa/parser/cxfa_signdata.h b/xfa/fxfa/parser/cxfa_signdata.h
index e28460d..4cb9676 100644
--- a/xfa/fxfa/parser/cxfa_signdata.h
+++ b/xfa/fxfa/parser/cxfa_signdata.h
@@ -11,8 +11,11 @@
 
 class CXFA_SignData final : public CXFA_Node {
  public:
-  CXFA_SignData(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SignData() override;
+
+ private:
+  CXFA_SignData(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SIGNDATA_H_
diff --git a/xfa/fxfa/parser/cxfa_signing.h b/xfa/fxfa/parser/cxfa_signing.h
index 7c37403..af0ab00 100644
--- a/xfa/fxfa/parser/cxfa_signing.h
+++ b/xfa/fxfa/parser/cxfa_signing.h
@@ -11,8 +11,11 @@
 
 class CXFA_Signing final : public CXFA_Node {
  public:
-  CXFA_Signing(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Signing() override;
+
+ private:
+  CXFA_Signing(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SIGNING_H_
diff --git a/xfa/fxfa/parser/cxfa_silentprint.h b/xfa/fxfa/parser/cxfa_silentprint.h
index 378084d..3288ee0 100644
--- a/xfa/fxfa/parser/cxfa_silentprint.h
+++ b/xfa/fxfa/parser/cxfa_silentprint.h
@@ -11,8 +11,11 @@
 
 class CXFA_SilentPrint final : public CXFA_Node {
  public:
-  CXFA_SilentPrint(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SilentPrint() override;
+
+ private:
+  CXFA_SilentPrint(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SILENTPRINT_H_
diff --git a/xfa/fxfa/parser/cxfa_soapaction.h b/xfa/fxfa/parser/cxfa_soapaction.h
index b7f7526..9ea850a 100644
--- a/xfa/fxfa/parser/cxfa_soapaction.h
+++ b/xfa/fxfa/parser/cxfa_soapaction.h
@@ -11,8 +11,11 @@
 
 class CXFA_SoapAction final : public CXFA_Node {
  public:
-  CXFA_SoapAction(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SoapAction() override;
+
+ private:
+  CXFA_SoapAction(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SOAPACTION_H_
diff --git a/xfa/fxfa/parser/cxfa_soapaddress.h b/xfa/fxfa/parser/cxfa_soapaddress.h
index 130ddf3..d62ff56 100644
--- a/xfa/fxfa/parser/cxfa_soapaddress.h
+++ b/xfa/fxfa/parser/cxfa_soapaddress.h
@@ -11,8 +11,11 @@
 
 class CXFA_SoapAddress final : public CXFA_Node {
  public:
-  CXFA_SoapAddress(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SoapAddress() override;
+
+ private:
+  CXFA_SoapAddress(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SOAPADDRESS_H_
diff --git a/xfa/fxfa/parser/cxfa_solid.h b/xfa/fxfa/parser/cxfa_solid.h
index 28666ef..8c6eed0 100644
--- a/xfa/fxfa/parser/cxfa_solid.h
+++ b/xfa/fxfa/parser/cxfa_solid.h
@@ -11,8 +11,11 @@
 
 class CXFA_Solid final : public CXFA_Node {
  public:
-  CXFA_Solid(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Solid() override;
+
+ private:
+  CXFA_Solid(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SOLID_H_
diff --git a/xfa/fxfa/parser/cxfa_source.h b/xfa/fxfa/parser/cxfa_source.h
index 96af083..784ead5 100644
--- a/xfa/fxfa/parser/cxfa_source.h
+++ b/xfa/fxfa/parser/cxfa_source.h
@@ -11,8 +11,11 @@
 
 class CXFA_Source final : public CXFA_Node {
  public:
-  CXFA_Source(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Source() override;
+
+ private:
+  CXFA_Source(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SOURCE_H_
diff --git a/xfa/fxfa/parser/cxfa_sourceset.h b/xfa/fxfa/parser/cxfa_sourceset.h
index c31b94c..d013004 100644
--- a/xfa/fxfa/parser/cxfa_sourceset.h
+++ b/xfa/fxfa/parser/cxfa_sourceset.h
@@ -11,8 +11,11 @@
 
 class CXFA_SourceSet final : public CXFA_Node {
  public:
-  CXFA_SourceSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SourceSet() override;
+
+ private:
+  CXFA_SourceSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SOURCESET_H_
diff --git a/xfa/fxfa/parser/cxfa_speak.h b/xfa/fxfa/parser/cxfa_speak.h
index 5497927..6062d4c 100644
--- a/xfa/fxfa/parser/cxfa_speak.h
+++ b/xfa/fxfa/parser/cxfa_speak.h
@@ -11,8 +11,11 @@
 
 class CXFA_Speak final : public CXFA_Node {
  public:
-  CXFA_Speak(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Speak() override;
+
+ private:
+  CXFA_Speak(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SPEAK_H_
diff --git a/xfa/fxfa/parser/cxfa_staple.h b/xfa/fxfa/parser/cxfa_staple.h
index 44ef654..47b04fd 100644
--- a/xfa/fxfa/parser/cxfa_staple.h
+++ b/xfa/fxfa/parser/cxfa_staple.h
@@ -11,8 +11,11 @@
 
 class CXFA_Staple final : public CXFA_Node {
  public:
-  CXFA_Staple(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Staple() override;
+
+ private:
+  CXFA_Staple(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_STAPLE_H_
diff --git a/xfa/fxfa/parser/cxfa_startnode.h b/xfa/fxfa/parser/cxfa_startnode.h
index b8bab06..301f24b 100644
--- a/xfa/fxfa/parser/cxfa_startnode.h
+++ b/xfa/fxfa/parser/cxfa_startnode.h
@@ -11,8 +11,11 @@
 
 class CXFA_StartNode final : public CXFA_Node {
  public:
-  CXFA_StartNode(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_StartNode() override;
+
+ private:
+  CXFA_StartNode(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_STARTNODE_H_
diff --git a/xfa/fxfa/parser/cxfa_startpage.h b/xfa/fxfa/parser/cxfa_startpage.h
index ae0ecee..d1f93b5 100644
--- a/xfa/fxfa/parser/cxfa_startpage.h
+++ b/xfa/fxfa/parser/cxfa_startpage.h
@@ -11,8 +11,11 @@
 
 class CXFA_StartPage final : public CXFA_Node {
  public:
-  CXFA_StartPage(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_StartPage() override;
+
+ private:
+  CXFA_StartPage(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_STARTPAGE_H_
diff --git a/xfa/fxfa/parser/cxfa_stipple.h b/xfa/fxfa/parser/cxfa_stipple.h
index af5581f..396f89f 100644
--- a/xfa/fxfa/parser/cxfa_stipple.h
+++ b/xfa/fxfa/parser/cxfa_stipple.h
@@ -18,7 +18,7 @@
  public:
   static int32_t GetDefaultRate() { return 50; }
 
-  CXFA_Stipple(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Stipple() override;
 
   void Draw(CXFA_Graphics* pGS,
@@ -27,6 +27,8 @@
             const CFX_Matrix& matrix);
 
  private:
+  CXFA_Stipple(CXFA_Document* doc, XFA_PacketType packet);
+
   CXFA_Color* GetColorIfExists();
   int32_t GetRate();
 };
diff --git a/xfa/fxfa/parser/cxfa_stroke.h b/xfa/fxfa/parser/cxfa_stroke.h
index c87bc50..e76d865 100644
--- a/xfa/fxfa/parser/cxfa_stroke.h
+++ b/xfa/fxfa/parser/cxfa_stroke.h
@@ -28,6 +28,7 @@
 
 class CXFA_Stroke : public CXFA_Node {
  public:
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Stroke() override;
 
   bool IsCorner() const { return GetElementType() == XFA_Element::Corner; }
diff --git a/xfa/fxfa/parser/cxfa_subform.h b/xfa/fxfa/parser/cxfa_subform.h
index 3d16d10..8b43fca 100644
--- a/xfa/fxfa/parser/cxfa_subform.h
+++ b/xfa/fxfa/parser/cxfa_subform.h
@@ -11,8 +11,11 @@
 
 class CXFA_Subform final : public CXFA_Node {
  public:
-  CXFA_Subform(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Subform() override;
+
+ private:
+  CXFA_Subform(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBFORM_H_
diff --git a/xfa/fxfa/parser/cxfa_subformset.h b/xfa/fxfa/parser/cxfa_subformset.h
index 12b9e9f..ab82322 100644
--- a/xfa/fxfa/parser/cxfa_subformset.h
+++ b/xfa/fxfa/parser/cxfa_subformset.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubformSet final : public CXFA_Node {
  public:
-  CXFA_SubformSet(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubformSet() override;
+
+ private:
+  CXFA_SubformSet(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBFORMSET_H_
diff --git a/xfa/fxfa/parser/cxfa_subjectdn.h b/xfa/fxfa/parser/cxfa_subjectdn.h
index a4d94d7..6ccbed7 100644
--- a/xfa/fxfa/parser/cxfa_subjectdn.h
+++ b/xfa/fxfa/parser/cxfa_subjectdn.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubjectDN final : public CXFA_Node {
  public:
-  CXFA_SubjectDN(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubjectDN() override;
+
+ private:
+  CXFA_SubjectDN(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBJECTDN_H_
diff --git a/xfa/fxfa/parser/cxfa_subjectdns.h b/xfa/fxfa/parser/cxfa_subjectdns.h
index 03d770b..6e66991 100644
--- a/xfa/fxfa/parser/cxfa_subjectdns.h
+++ b/xfa/fxfa/parser/cxfa_subjectdns.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubjectDNs final : public CXFA_Node {
  public:
-  CXFA_SubjectDNs(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubjectDNs() override;
+
+ private:
+  CXFA_SubjectDNs(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBJECTDNS_H_
diff --git a/xfa/fxfa/parser/cxfa_submit.h b/xfa/fxfa/parser/cxfa_submit.h
index 13cad86..1d92ffb 100644
--- a/xfa/fxfa/parser/cxfa_submit.h
+++ b/xfa/fxfa/parser/cxfa_submit.h
@@ -12,13 +12,16 @@
 
 class CXFA_Submit final : public CXFA_Node {
  public:
-  CXFA_Submit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Submit() override;
 
   bool IsSubmitEmbedPDF();
   XFA_AttributeValue GetSubmitFormat();
   WideString GetSubmitTarget();
   WideString GetSubmitXDPContent();
+
+ private:
+  CXFA_Submit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBMIT_H_
diff --git a/xfa/fxfa/parser/cxfa_submitformat.h b/xfa/fxfa/parser/cxfa_submitformat.h
index bd6df26..87714bc 100644
--- a/xfa/fxfa/parser/cxfa_submitformat.h
+++ b/xfa/fxfa/parser/cxfa_submitformat.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubmitFormat final : public CXFA_Node {
  public:
-  CXFA_SubmitFormat(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubmitFormat() override;
+
+ private:
+  CXFA_SubmitFormat(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBMITFORMAT_H_
diff --git a/xfa/fxfa/parser/cxfa_submiturl.h b/xfa/fxfa/parser/cxfa_submiturl.h
index f1914db..f0d8512 100644
--- a/xfa/fxfa/parser/cxfa_submiturl.h
+++ b/xfa/fxfa/parser/cxfa_submiturl.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubmitUrl final : public CXFA_Node {
  public:
-  CXFA_SubmitUrl(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubmitUrl() override;
+
+ private:
+  CXFA_SubmitUrl(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBMITURL_H_
diff --git a/xfa/fxfa/parser/cxfa_subsetbelow.h b/xfa/fxfa/parser/cxfa_subsetbelow.h
index 230a563..70b9633 100644
--- a/xfa/fxfa/parser/cxfa_subsetbelow.h
+++ b/xfa/fxfa/parser/cxfa_subsetbelow.h
@@ -11,8 +11,11 @@
 
 class CXFA_SubsetBelow final : public CXFA_Node {
  public:
-  CXFA_SubsetBelow(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SubsetBelow() override;
+
+ private:
+  CXFA_SubsetBelow(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUBSETBELOW_H_
diff --git a/xfa/fxfa/parser/cxfa_suppressbanner.h b/xfa/fxfa/parser/cxfa_suppressbanner.h
index 40057d0..bb1a3eb 100644
--- a/xfa/fxfa/parser/cxfa_suppressbanner.h
+++ b/xfa/fxfa/parser/cxfa_suppressbanner.h
@@ -11,8 +11,11 @@
 
 class CXFA_SuppressBanner final : public CXFA_Node {
  public:
-  CXFA_SuppressBanner(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_SuppressBanner() override;
+
+ private:
+  CXFA_SuppressBanner(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_SUPPRESSBANNER_H_
diff --git a/xfa/fxfa/parser/cxfa_tagged.h b/xfa/fxfa/parser/cxfa_tagged.h
index ff54423..e10c3ed 100644
--- a/xfa/fxfa/parser/cxfa_tagged.h
+++ b/xfa/fxfa/parser/cxfa_tagged.h
@@ -11,8 +11,11 @@
 
 class CXFA_Tagged final : public CXFA_Node {
  public:
-  CXFA_Tagged(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Tagged() override;
+
+ private:
+  CXFA_Tagged(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TAGGED_H_
diff --git a/xfa/fxfa/parser/cxfa_template.h b/xfa/fxfa/parser/cxfa_template.h
index fa9b999..59aa793 100644
--- a/xfa/fxfa/parser/cxfa_template.h
+++ b/xfa/fxfa/parser/cxfa_template.h
@@ -11,8 +11,11 @@
 
 class CXFA_Template final : public CXFA_Node {
  public:
-  CXFA_Template(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Template() override;
+
+ private:
+  CXFA_Template(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TEMPLATE_H_
diff --git a/xfa/fxfa/parser/cxfa_templatecache.h b/xfa/fxfa/parser/cxfa_templatecache.h
index dd0136d..171df3d 100644
--- a/xfa/fxfa/parser/cxfa_templatecache.h
+++ b/xfa/fxfa/parser/cxfa_templatecache.h
@@ -11,8 +11,11 @@
 
 class CXFA_TemplateCache final : public CXFA_Node {
  public:
-  CXFA_TemplateCache(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TemplateCache() override;
+
+ private:
+  CXFA_TemplateCache(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TEMPLATECACHE_H_
diff --git a/xfa/fxfa/parser/cxfa_text.h b/xfa/fxfa/parser/cxfa_text.h
index 811ce1a..705c14c 100644
--- a/xfa/fxfa/parser/cxfa_text.h
+++ b/xfa/fxfa/parser/cxfa_text.h
@@ -12,10 +12,13 @@
 
 class CXFA_Text final : public CXFA_Node {
  public:
-  CXFA_Text(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Text() override;
 
   WideString GetContent();
+
+ private:
+  CXFA_Text(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TEXT_H_
diff --git a/xfa/fxfa/parser/cxfa_textedit.h b/xfa/fxfa/parser/cxfa_textedit.h
index d4cafa4..44af2cc 100644
--- a/xfa/fxfa/parser/cxfa_textedit.h
+++ b/xfa/fxfa/parser/cxfa_textedit.h
@@ -11,10 +11,13 @@
 
 class CXFA_TextEdit final : public CXFA_Node {
  public:
-  CXFA_TextEdit(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TextEdit() override;
 
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
+
+ private:
+  CXFA_TextEdit(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TEXTEDIT_H_
diff --git a/xfa/fxfa/parser/cxfa_thisproxy.cpp b/xfa/fxfa/parser/cxfa_thisproxy.cpp
index 5f538d5..17b5fa5 100644
--- a/xfa/fxfa/parser/cxfa_thisproxy.cpp
+++ b/xfa/fxfa/parser/cxfa_thisproxy.cpp
@@ -20,3 +20,9 @@
       m_pScriptNode(pScriptNode) {}
 
 CXFA_ThisProxy::~CXFA_ThisProxy() = default;
+
+void CXFA_ThisProxy::Trace(cppgc::Visitor* visitor) const {
+  CXFA_Object::Trace(visitor);
+  visitor->Trace(m_pThisNode);
+  visitor->Trace(m_pScriptNode);
+}
diff --git a/xfa/fxfa/parser/cxfa_thisproxy.h b/xfa/fxfa/parser/cxfa_thisproxy.h
index 4ec6e4a..539c1c6 100644
--- a/xfa/fxfa/parser/cxfa_thisproxy.h
+++ b/xfa/fxfa/parser/cxfa_thisproxy.h
@@ -8,21 +8,27 @@
 #define XFA_FXFA_PARSER_CXFA_THISPROXY_H_
 
 #include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
 
 class CXFA_Node;
 
 class CXFA_ThisProxy final : public CXFA_Object {
  public:
-  CXFA_ThisProxy(CXFA_Node* pThisNode, CXFA_Node* pScriptNode);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ThisProxy() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   CXFA_Node* GetThisNode() const { return m_pThisNode.Get(); }
   CXFA_Node* GetScriptNode() const { return m_pScriptNode.Get(); }
 
  private:
-  UnownedPtr<CXFA_Node> m_pThisNode;
-  UnownedPtr<CXFA_Node> m_pScriptNode;
+  CXFA_ThisProxy(CXFA_Node* pThisNode, CXFA_Node* pScriptNode);
+
+  cppgc::Member<CXFA_Node> m_pThisNode;
+  cppgc::Member<CXFA_Node> m_pScriptNode;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_THISPROXY_H_
diff --git a/xfa/fxfa/parser/cxfa_threshold.h b/xfa/fxfa/parser/cxfa_threshold.h
index 597b134..2ef20bf 100644
--- a/xfa/fxfa/parser/cxfa_threshold.h
+++ b/xfa/fxfa/parser/cxfa_threshold.h
@@ -11,8 +11,11 @@
 
 class CXFA_Threshold final : public CXFA_Node {
  public:
-  CXFA_Threshold(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Threshold() override;
+
+ private:
+  CXFA_Threshold(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_THRESHOLD_H_
diff --git a/xfa/fxfa/parser/cxfa_time.h b/xfa/fxfa/parser/cxfa_time.h
index c189bc5..b9126d6 100644
--- a/xfa/fxfa/parser/cxfa_time.h
+++ b/xfa/fxfa/parser/cxfa_time.h
@@ -11,8 +11,11 @@
 
 class CXFA_Time final : public CXFA_Node {
  public:
-  CXFA_Time(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Time() override;
+
+ private:
+  CXFA_Time(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TIME_H_
diff --git a/xfa/fxfa/parser/cxfa_timepattern.h b/xfa/fxfa/parser/cxfa_timepattern.h
index 7c150a9..965b497 100644
--- a/xfa/fxfa/parser/cxfa_timepattern.h
+++ b/xfa/fxfa/parser/cxfa_timepattern.h
@@ -11,8 +11,11 @@
 
 class CXFA_TimePattern final : public CXFA_Node {
  public:
-  CXFA_TimePattern(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TimePattern() override;
+
+ private:
+  CXFA_TimePattern(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TIMEPATTERN_H_
diff --git a/xfa/fxfa/parser/cxfa_timepatterns.h b/xfa/fxfa/parser/cxfa_timepatterns.h
index 13c05c8..8e77b26 100644
--- a/xfa/fxfa/parser/cxfa_timepatterns.h
+++ b/xfa/fxfa/parser/cxfa_timepatterns.h
@@ -11,8 +11,11 @@
 
 class CXFA_TimePatterns final : public CXFA_Node {
  public:
-  CXFA_TimePatterns(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TimePatterns() override;
+
+ private:
+  CXFA_TimePatterns(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TIMEPATTERNS_H_
diff --git a/xfa/fxfa/parser/cxfa_timestamp.h b/xfa/fxfa/parser/cxfa_timestamp.h
index 6a6c1ac..86d6687 100644
--- a/xfa/fxfa/parser/cxfa_timestamp.h
+++ b/xfa/fxfa/parser/cxfa_timestamp.h
@@ -11,8 +11,11 @@
 
 class CXFA_TimeStamp final : public CXFA_Node {
  public:
-  CXFA_TimeStamp(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TimeStamp() override;
+
+ private:
+  CXFA_TimeStamp(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TIMESTAMP_H_
diff --git a/xfa/fxfa/parser/cxfa_to.h b/xfa/fxfa/parser/cxfa_to.h
index 8510bc2..730ffc9 100644
--- a/xfa/fxfa/parser/cxfa_to.h
+++ b/xfa/fxfa/parser/cxfa_to.h
@@ -11,8 +11,11 @@
 
 class CXFA_To final : public CXFA_Node {
  public:
-  CXFA_To(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_To() override;
+
+ private:
+  CXFA_To(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TO_H_
diff --git a/xfa/fxfa/parser/cxfa_tooltip.h b/xfa/fxfa/parser/cxfa_tooltip.h
index f46ca62..eb85ab0 100644
--- a/xfa/fxfa/parser/cxfa_tooltip.h
+++ b/xfa/fxfa/parser/cxfa_tooltip.h
@@ -11,8 +11,11 @@
 
 class CXFA_ToolTip final : public CXFA_Node {
  public:
-  CXFA_ToolTip(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ToolTip() override;
+
+ private:
+  CXFA_ToolTip(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TOOLTIP_H_
diff --git a/xfa/fxfa/parser/cxfa_trace.h b/xfa/fxfa/parser/cxfa_trace.h
index 1d76f73..7e6775b 100644
--- a/xfa/fxfa/parser/cxfa_trace.h
+++ b/xfa/fxfa/parser/cxfa_trace.h
@@ -11,8 +11,11 @@
 
 class CXFA_Trace final : public CXFA_Node {
  public:
-  CXFA_Trace(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Trace() override;
+
+ private:
+  CXFA_Trace(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TRACE_H_
diff --git a/xfa/fxfa/parser/cxfa_transform.h b/xfa/fxfa/parser/cxfa_transform.h
index 6409c6c..1ae05b2 100644
--- a/xfa/fxfa/parser/cxfa_transform.h
+++ b/xfa/fxfa/parser/cxfa_transform.h
@@ -11,8 +11,11 @@
 
 class CXFA_Transform final : public CXFA_Node {
  public:
-  CXFA_Transform(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Transform() override;
+
+ private:
+  CXFA_Transform(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TRANSFORM_H_
diff --git a/xfa/fxfa/parser/cxfa_traversal.h b/xfa/fxfa/parser/cxfa_traversal.h
index 154211b..5124968 100644
--- a/xfa/fxfa/parser/cxfa_traversal.h
+++ b/xfa/fxfa/parser/cxfa_traversal.h
@@ -11,8 +11,11 @@
 
 class CXFA_Traversal final : public CXFA_Node {
  public:
-  CXFA_Traversal(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Traversal() override;
+
+ private:
+  CXFA_Traversal(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TRAVERSAL_H_
diff --git a/xfa/fxfa/parser/cxfa_traverse.h b/xfa/fxfa/parser/cxfa_traverse.h
index dec5b89..d190619 100644
--- a/xfa/fxfa/parser/cxfa_traverse.h
+++ b/xfa/fxfa/parser/cxfa_traverse.h
@@ -11,8 +11,11 @@
 
 class CXFA_Traverse final : public CXFA_Node {
  public:
-  CXFA_Traverse(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Traverse() override;
+
+ private:
+  CXFA_Traverse(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TRAVERSE_H_
diff --git a/xfa/fxfa/parser/cxfa_treelist.h b/xfa/fxfa/parser/cxfa_treelist.h
index a194e32..e2cfac7 100644
--- a/xfa/fxfa/parser/cxfa_treelist.h
+++ b/xfa/fxfa/parser/cxfa_treelist.h
@@ -14,10 +14,13 @@
 
 class CXFA_TreeList : public CXFA_List {
  public:
-  explicit CXFA_TreeList(CXFA_Document* pDocument);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_TreeList() override;
 
   CXFA_Node* NamedItem(WideStringView wsName);
+
+ protected:
+  explicit CXFA_TreeList(CXFA_Document* pDocument);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TREELIST_H_
diff --git a/xfa/fxfa/parser/cxfa_type.h b/xfa/fxfa/parser/cxfa_type.h
index ef696fd..442efdf 100644
--- a/xfa/fxfa/parser/cxfa_type.h
+++ b/xfa/fxfa/parser/cxfa_type.h
@@ -11,8 +11,11 @@
 
 class CXFA_Type final : public CXFA_Node {
  public:
-  CXFA_Type(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Type() override;
+
+ private:
+  CXFA_Type(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TYPE_H_
diff --git a/xfa/fxfa/parser/cxfa_typeface.h b/xfa/fxfa/parser/cxfa_typeface.h
index 7b07cae..a254b71 100644
--- a/xfa/fxfa/parser/cxfa_typeface.h
+++ b/xfa/fxfa/parser/cxfa_typeface.h
@@ -11,8 +11,11 @@
 
 class CXFA_Typeface final : public CXFA_Node {
  public:
-  CXFA_Typeface(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Typeface() override;
+
+ private:
+  CXFA_Typeface(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TYPEFACE_H_
diff --git a/xfa/fxfa/parser/cxfa_typefaces.h b/xfa/fxfa/parser/cxfa_typefaces.h
index b65c57d..76993ee 100644
--- a/xfa/fxfa/parser/cxfa_typefaces.h
+++ b/xfa/fxfa/parser/cxfa_typefaces.h
@@ -11,8 +11,11 @@
 
 class CXFA_Typefaces final : public CXFA_Node {
  public:
-  CXFA_Typefaces(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Typefaces() override;
+
+ private:
+  CXFA_Typefaces(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_TYPEFACES_H_
diff --git a/xfa/fxfa/parser/cxfa_ui.h b/xfa/fxfa/parser/cxfa_ui.h
index d479e95..ee765b4 100644
--- a/xfa/fxfa/parser/cxfa_ui.h
+++ b/xfa/fxfa/parser/cxfa_ui.h
@@ -11,10 +11,13 @@
 
 class CXFA_Ui final : public CXFA_Node {
  public:
-  CXFA_Ui(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Ui() override;
 
   bool IsAOneOfChild(CXFA_Node* child) const;
+
+ private:
+  CXFA_Ui(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_UI_H_
diff --git a/xfa/fxfa/parser/cxfa_update.h b/xfa/fxfa/parser/cxfa_update.h
index 3e6bb6c..dea33f6 100644
--- a/xfa/fxfa/parser/cxfa_update.h
+++ b/xfa/fxfa/parser/cxfa_update.h
@@ -11,8 +11,11 @@
 
 class CXFA_Update final : public CXFA_Node {
  public:
-  CXFA_Update(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Update() override;
+
+ private:
+  CXFA_Update(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_UPDATE_H_
diff --git a/xfa/fxfa/parser/cxfa_uri.h b/xfa/fxfa/parser/cxfa_uri.h
index 96252fc..2d2a306 100644
--- a/xfa/fxfa/parser/cxfa_uri.h
+++ b/xfa/fxfa/parser/cxfa_uri.h
@@ -11,8 +11,11 @@
 
 class CXFA_Uri final : public CXFA_Node {
  public:
-  CXFA_Uri(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Uri() override;
+
+ private:
+  CXFA_Uri(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_URI_H_
diff --git a/xfa/fxfa/parser/cxfa_user.h b/xfa/fxfa/parser/cxfa_user.h
index eca1a37..018769b 100644
--- a/xfa/fxfa/parser/cxfa_user.h
+++ b/xfa/fxfa/parser/cxfa_user.h
@@ -11,8 +11,11 @@
 
 class CXFA_User final : public CXFA_Node {
  public:
-  CXFA_User(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_User() override;
+
+ private:
+  CXFA_User(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_USER_H_
diff --git a/xfa/fxfa/parser/cxfa_validate.h b/xfa/fxfa/parser/cxfa_validate.h
index 0018cf9..8fdf5dd 100644
--- a/xfa/fxfa/parser/cxfa_validate.h
+++ b/xfa/fxfa/parser/cxfa_validate.h
@@ -13,7 +13,7 @@
 
 class CXFA_Validate final : public CXFA_Node {
  public:
-  CXFA_Validate(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Validate() override;
 
   XFA_AttributeValue GetFormatTest();
@@ -34,6 +34,8 @@
   CXFA_Script* GetScriptIfExists();
 
  private:
+  CXFA_Validate(CXFA_Document* doc, XFA_PacketType packet);
+
   WideString GetMessageText(const WideString& wsMessageType);
   void SetMessageText(const WideString& wsMessageType,
                       const WideString& wsMessage);
diff --git a/xfa/fxfa/parser/cxfa_validateapprovalsignatures.h b/xfa/fxfa/parser/cxfa_validateapprovalsignatures.h
index 0504168..ad35b0c 100644
--- a/xfa/fxfa/parser/cxfa_validateapprovalsignatures.h
+++ b/xfa/fxfa/parser/cxfa_validateapprovalsignatures.h
@@ -11,8 +11,11 @@
 
 class CXFA_ValidateApprovalSignatures final : public CXFA_Node {
  public:
-  CXFA_ValidateApprovalSignatures(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ValidateApprovalSignatures() override;
+
+ private:
+  CXFA_ValidateApprovalSignatures(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VALIDATEAPPROVALSIGNATURES_H_
diff --git a/xfa/fxfa/parser/cxfa_validationmessaging.h b/xfa/fxfa/parser/cxfa_validationmessaging.h
index 1131788..31139e3 100644
--- a/xfa/fxfa/parser/cxfa_validationmessaging.h
+++ b/xfa/fxfa/parser/cxfa_validationmessaging.h
@@ -11,8 +11,11 @@
 
 class CXFA_ValidationMessaging final : public CXFA_Node {
  public:
-  CXFA_ValidationMessaging(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ValidationMessaging() override;
+
+ private:
+  CXFA_ValidationMessaging(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VALIDATIONMESSAGING_H_
diff --git a/xfa/fxfa/parser/cxfa_value.h b/xfa/fxfa/parser/cxfa_value.h
index ccd4c2c..4cb2f94 100644
--- a/xfa/fxfa/parser/cxfa_value.h
+++ b/xfa/fxfa/parser/cxfa_value.h
@@ -19,7 +19,7 @@
 
 class CXFA_Value final : public CXFA_Node {
  public:
-  CXFA_Value(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Value() override;
 
   XFA_Element GetChildValueClassID() const;
@@ -30,6 +30,9 @@
   CXFA_Text* GetTextIfExists() const;
   CXFA_ExData* GetExDataIfExists() const;
   CXFA_Image* GetImageIfExists() const;
+
+ private:
+  CXFA_Value(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VALUE_H_
diff --git a/xfa/fxfa/parser/cxfa_variables.h b/xfa/fxfa/parser/cxfa_variables.h
index b9f6d72..67ea571 100644
--- a/xfa/fxfa/parser/cxfa_variables.h
+++ b/xfa/fxfa/parser/cxfa_variables.h
@@ -11,8 +11,11 @@
 
 class CXFA_Variables final : public CXFA_Node {
  public:
-  CXFA_Variables(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Variables() override;
+
+ private:
+  CXFA_Variables(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VARIABLES_H_
diff --git a/xfa/fxfa/parser/cxfa_version.h b/xfa/fxfa/parser/cxfa_version.h
index 4b4f425..492aeb1 100644
--- a/xfa/fxfa/parser/cxfa_version.h
+++ b/xfa/fxfa/parser/cxfa_version.h
@@ -11,8 +11,11 @@
 
 class CXFA_Version final : public CXFA_Node {
  public:
-  CXFA_Version(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Version() override;
+
+ private:
+  CXFA_Version(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VERSION_H_
diff --git a/xfa/fxfa/parser/cxfa_versioncontrol.h b/xfa/fxfa/parser/cxfa_versioncontrol.h
index 733b817..ef79198 100644
--- a/xfa/fxfa/parser/cxfa_versioncontrol.h
+++ b/xfa/fxfa/parser/cxfa_versioncontrol.h
@@ -11,8 +11,11 @@
 
 class CXFA_VersionControl final : public CXFA_Node {
  public:
-  CXFA_VersionControl(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_VersionControl() override;
+
+ private:
+  CXFA_VersionControl(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VERSIONCONTROL_H_
diff --git a/xfa/fxfa/parser/cxfa_viewerpreferences.h b/xfa/fxfa/parser/cxfa_viewerpreferences.h
index 229061f..ff70980 100644
--- a/xfa/fxfa/parser/cxfa_viewerpreferences.h
+++ b/xfa/fxfa/parser/cxfa_viewerpreferences.h
@@ -11,8 +11,11 @@
 
 class CXFA_ViewerPreferences final : public CXFA_Node {
  public:
-  CXFA_ViewerPreferences(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_ViewerPreferences() override;
+
+ private:
+  CXFA_ViewerPreferences(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_VIEWERPREFERENCES_H_
diff --git a/xfa/fxfa/parser/cxfa_webclient.h b/xfa/fxfa/parser/cxfa_webclient.h
index 41da046..8d9b7a3 100644
--- a/xfa/fxfa/parser/cxfa_webclient.h
+++ b/xfa/fxfa/parser/cxfa_webclient.h
@@ -11,8 +11,11 @@
 
 class CXFA_WebClient final : public CXFA_Node {
  public:
-  CXFA_WebClient(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_WebClient() override;
+
+ private:
+  CXFA_WebClient(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_WEBCLIENT_H_
diff --git a/xfa/fxfa/parser/cxfa_whitespace.h b/xfa/fxfa/parser/cxfa_whitespace.h
index 096a2da..2a55ed9 100644
--- a/xfa/fxfa/parser/cxfa_whitespace.h
+++ b/xfa/fxfa/parser/cxfa_whitespace.h
@@ -11,8 +11,11 @@
 
 class CXFA_Whitespace final : public CXFA_Node {
  public:
-  CXFA_Whitespace(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Whitespace() override;
+
+ private:
+  CXFA_Whitespace(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_WHITESPACE_H_
diff --git a/xfa/fxfa/parser/cxfa_window.h b/xfa/fxfa/parser/cxfa_window.h
index fc2fcb7..0e4f170 100644
--- a/xfa/fxfa/parser/cxfa_window.h
+++ b/xfa/fxfa/parser/cxfa_window.h
@@ -11,8 +11,11 @@
 
 class CXFA_Window final : public CXFA_Node {
  public:
-  CXFA_Window(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Window() override;
+
+ private:
+  CXFA_Window(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_WINDOW_H_
diff --git a/xfa/fxfa/parser/cxfa_wsdladdress.h b/xfa/fxfa/parser/cxfa_wsdladdress.h
index e65bd6f..037c27f 100644
--- a/xfa/fxfa/parser/cxfa_wsdladdress.h
+++ b/xfa/fxfa/parser/cxfa_wsdladdress.h
@@ -11,8 +11,11 @@
 
 class CXFA_WsdlAddress final : public CXFA_Node {
  public:
-  CXFA_WsdlAddress(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_WsdlAddress() override;
+
+ private:
+  CXFA_WsdlAddress(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_WSDLADDRESS_H_
diff --git a/xfa/fxfa/parser/cxfa_wsdlconnection.h b/xfa/fxfa/parser/cxfa_wsdlconnection.h
index b2238fd..b51bd1b 100644
--- a/xfa/fxfa/parser/cxfa_wsdlconnection.h
+++ b/xfa/fxfa/parser/cxfa_wsdlconnection.h
@@ -11,8 +11,11 @@
 
 class CXFA_WsdlConnection final : public CXFA_Node {
  public:
-  CXFA_WsdlConnection(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_WsdlConnection() override;
+
+ private:
+  CXFA_WsdlConnection(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_WSDLCONNECTION_H_
diff --git a/xfa/fxfa/parser/cxfa_xdc.h b/xfa/fxfa/parser/cxfa_xdc.h
index 81cbb57..78adab8 100644
--- a/xfa/fxfa/parser/cxfa_xdc.h
+++ b/xfa/fxfa/parser/cxfa_xdc.h
@@ -11,8 +11,11 @@
 
 class CXFA_Xdc final : public CXFA_Node {
  public:
-  CXFA_Xdc(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Xdc() override;
+
+ private:
+  CXFA_Xdc(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XDC_H_
diff --git a/xfa/fxfa/parser/cxfa_xdp.h b/xfa/fxfa/parser/cxfa_xdp.h
index 16ad5d8..ca8a618 100644
--- a/xfa/fxfa/parser/cxfa_xdp.h
+++ b/xfa/fxfa/parser/cxfa_xdp.h
@@ -11,8 +11,11 @@
 
 class CXFA_Xdp final : public CXFA_Node {
  public:
-  CXFA_Xdp(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Xdp() override;
+
+ private:
+  CXFA_Xdp(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XDP_H_
diff --git a/xfa/fxfa/parser/cxfa_xfa.h b/xfa/fxfa/parser/cxfa_xfa.h
index d7d33df..b8445fd 100644
--- a/xfa/fxfa/parser/cxfa_xfa.h
+++ b/xfa/fxfa/parser/cxfa_xfa.h
@@ -11,8 +11,11 @@
 
 class CXFA_Xfa final : public CXFA_Node {
  public:
-  CXFA_Xfa(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Xfa() override;
+
+ private:
+  CXFA_Xfa(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XFA_H_
diff --git a/xfa/fxfa/parser/cxfa_xmlconnection.h b/xfa/fxfa/parser/cxfa_xmlconnection.h
index 33cc038..7caaa09 100644
--- a/xfa/fxfa/parser/cxfa_xmlconnection.h
+++ b/xfa/fxfa/parser/cxfa_xmlconnection.h
@@ -11,8 +11,11 @@
 
 class CXFA_XmlConnection final : public CXFA_Node {
  public:
-  CXFA_XmlConnection(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_XmlConnection() override;
+
+ private:
+  CXFA_XmlConnection(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XMLCONNECTION_H_
diff --git a/xfa/fxfa/parser/cxfa_xsdconnection.h b/xfa/fxfa/parser/cxfa_xsdconnection.h
index 8cdef80..2293c25 100644
--- a/xfa/fxfa/parser/cxfa_xsdconnection.h
+++ b/xfa/fxfa/parser/cxfa_xsdconnection.h
@@ -11,8 +11,11 @@
 
 class CXFA_XsdConnection final : public CXFA_Node {
  public:
-  CXFA_XsdConnection(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_XsdConnection() override;
+
+ private:
+  CXFA_XsdConnection(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XSDCONNECTION_H_
diff --git a/xfa/fxfa/parser/cxfa_xsl.h b/xfa/fxfa/parser/cxfa_xsl.h
index 1be8d4b..76d89e9 100644
--- a/xfa/fxfa/parser/cxfa_xsl.h
+++ b/xfa/fxfa/parser/cxfa_xsl.h
@@ -11,8 +11,11 @@
 
 class CXFA_Xsl final : public CXFA_Node {
  public:
-  CXFA_Xsl(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Xsl() override;
+
+ private:
+  CXFA_Xsl(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_XSL_H_
diff --git a/xfa/fxfa/parser/cxfa_zpl.h b/xfa/fxfa/parser/cxfa_zpl.h
index 6433015..1845778 100644
--- a/xfa/fxfa/parser/cxfa_zpl.h
+++ b/xfa/fxfa/parser/cxfa_zpl.h
@@ -11,8 +11,11 @@
 
 class CXFA_Zpl final : public CXFA_Node {
  public:
-  CXFA_Zpl(CXFA_Document* doc, XFA_PacketType packet);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Zpl() override;
+
+ private:
+  CXFA_Zpl(CXFA_Document* doc, XFA_PacketType packet);
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_ZPL_H_