Initialize CPPGC heap with kNoConservativeStack.

Otherwise, we might encounter a partially-constructed object,
which is conservatively scanned, rather than Traced. This works
fine so long as all the pointers are inline, but not with
std::list<> etc. where they may be out of line.

Roll back the protections introduced earlier, as tracing such
an object was in fact a v8 bug.

Change-Id: If8d2373b3c91acebe7697ff4760eed97f3efb109
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73254
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/gc/container_trace.h b/fxjs/gc/container_trace.h
index c615a2a..23a03b9 100644
--- a/fxjs/gc/container_trace.h
+++ b/fxjs/gc/container_trace.h
@@ -17,10 +17,6 @@
 
 template <typename T, typename V = cppgc::Visitor>
 void ContainerTrace(V* visitor, const std::list<cppgc::Member<T>>& container) {
-  // Defend against CPPGC invoking Trace() on zero-initialized memory.
-  if (container.empty())
-    return;
-
   for (const auto& item : container)
     visitor->Trace(item);
 }
@@ -28,20 +24,12 @@
 template <typename T, typename U, typename V = cppgc::Visitor>
 void ContainerTrace(V* visitor,
                     const std::map<U, cppgc::Member<T>>& container) {
-  // Defend against CPPGC invoking Trace() on zero-initialized memory.
-  if (container.empty())
-    return;
-
   for (const auto& item : container)
     visitor->Trace(item.second);
 }
 
 template <typename T, typename V = cppgc::Visitor>
 void ContainerTrace(V* visitor, const std::set<cppgc::Member<T>>& container) {
-  // Defend against CPPGC invoking Trace() on zero-initialized memory.
-  if (container.empty())
-    return;
-
   for (const auto& item : container)
     visitor->Trace(item);
 }
diff --git a/fxjs/gc/container_trace_unittest.cpp b/fxjs/gc/container_trace_unittest.cpp
index 6133a0c..b02136a 100644
--- a/fxjs/gc/container_trace_unittest.cpp
+++ b/fxjs/gc/container_trace_unittest.cpp
@@ -34,107 +34,6 @@
 
 }  // namespace
 
-TEST(ContainerTrace, ZeroedListQuirk) {
-  using Type = std::list<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  // Can't trust iterators.
-  // EXPECT_NE(thing->begin(), thing->end());
-
-  // But we can trust empty() and guard with it.
-  EXPECT_TRUE(thing->empty());
-}
-
-TEST(ContainerTrace, ZeroedMapQuirk) {
-  using Type = std::map<int, cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  // Can't trust iterators.
-  // EXPECT_NE(thing->begin(), thing->end());
-
-  // But we can trust empty() and guard with it.
-  EXPECT_TRUE(thing->empty());
-}
-
-TEST(ContainerTrace, ZeroedSetQuirk) {
-  using Type = std::set<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  // Can't trust iterators.
-  // EXPECT_NE(thing->begin(), thing->end());
-
-  // But we can trust empty() and guard with it.
-  EXPECT_TRUE(thing->empty());
-}
-
-TEST(ContainerTrace, ZeroedVectorQuirk) {
-  using Type = std::vector<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  // Can trust iterators, no guard required.
-  EXPECT_EQ(thing->begin(), thing->end());
-}
-
-TEST(ContainerTrace, ZeroedListTrace) {
-  using Type = std::list<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  CountingVisitor cv;
-  ContainerTrace(&cv, *thing);
-  EXPECT_EQ(0, cv.call_count());
-}
-
-TEST(ContainerTrace, ZeroedMapTrace) {
-  using Type = std::map<int, cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  CountingVisitor cv;
-  ContainerTrace(&cv, *thing);
-  EXPECT_EQ(0, cv.call_count());
-}
-
-TEST(ContainerTrace, ZeroedSetTrace) {
-  using Type = std::set<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  CountingVisitor cv;
-  ContainerTrace(&cv, *thing);
-  EXPECT_EQ(0, cv.call_count());
-}
-
-TEST(ContainerTrace, ZeroedVectorTrace) {
-  using Type = std::vector<cppgc::Member<Thing>>;
-  uint8_t buffer[sizeof(Type)];
-  memset(&buffer, 0, sizeof(buffer));
-
-  auto* thing = reinterpret_cast<Type*>(buffer);
-
-  CountingVisitor cv;
-  ContainerTrace(&cv, *thing);
-  EXPECT_EQ(0, cv.call_count());
-}
-
 TEST(ContainerTrace, ActualListTrace) {
   std::list<cppgc::Member<Thing>> thing;
   thing.emplace_back(nullptr);
diff --git a/fxjs/gc/heap.cpp b/fxjs/gc/heap.cpp
index 4663763..2c02752 100644
--- a/fxjs/gc/heap.cpp
+++ b/fxjs/gc/heap.cpp
@@ -71,7 +71,10 @@
     return nullptr;
 
   ++g_platform_ref_count;
-  auto heap = cppgc::Heap::Create(std::make_shared<CFXGC_Platform>());
+  auto heap = cppgc::Heap::Create(
+      std::make_shared<CFXGC_Platform>(),
+      {{}, cppgc::Heap::StackSupport::kNoConservativeStackScan, {}});
+
   return FXGCScopedHeap(heap.release());
 }