sync to current upb and enable new unit test on upb

PiperOrigin-RevId: 518643876
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h
index 13f2cfd..3773e7f 100755
--- a/ruby/ext/google/protobuf_c/ruby-upb.h
+++ b/ruby/ext/google/protobuf_c/ruby-upb.h
@@ -167,6 +167,13 @@
 #define UPB_LONGJMP(buf, val) longjmp(buf, val)
 #endif
 
+#ifdef __GNUC__
+#define UPB_USE_C11_ATOMICS
+#define UPB_ATOMIC _Atomic
+#else
+#define UPB_ATOMIC
+#endif
+
 /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
 #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
 
@@ -347,6 +354,8 @@
 #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_
 #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_
 
+// Must be last.
+
 // The types a field can have. Note that this list is not identical to the
 // types defined in descriptor.proto, which gives INT32 and SINT32 separate
 // types (we distinguish the two with the "integer encoding" enum below).
@@ -396,6 +405,26 @@
 
 #define kUpb_FieldType_SizeOf 19
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) {
+  // clang-format off
+  const unsigned kUnpackableTypes =
+      (1 << kUpb_FieldType_String) |
+      (1 << kUpb_FieldType_Bytes) |
+      (1 << kUpb_FieldType_Message) |
+      (1 << kUpb_FieldType_Group);
+  // clang-format on
+  return (1 << type) & ~kUnpackableTypes;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
 #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */
 
 // Users should include array.h or map.h instead.
@@ -9442,25 +9471,134 @@
 
   /* When multiple arenas are fused together, each arena points to a parent
    * arena (root points to itself). The root tracks how many live arenas
-   * reference it. */
-  uint32_t refcount; /* Only used when a->parent == a */
-  struct upb_Arena* parent;
+   * reference it.
+   *
+   * The low bit is tagged:
+   *   0: pointer to parent
+   *   1: count, left shifted by one
+   */
+  UPB_ATOMIC uintptr_t parent_or_count;
 
   /* Linked list of blocks to free/cleanup. */
   _upb_MemBlock *freelist, *freelist_tail;
 };
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+UPB_INLINE bool _upb_Arena_IsTaggedRefcount(uintptr_t parent_or_count) {
+  return (parent_or_count & 1) == 1;
+}
 
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
+UPB_INLINE bool _upb_Arena_IsTaggedPointer(uintptr_t parent_or_count) {
+  return (parent_or_count & 1) == 0;
+}
+
+UPB_INLINE uint32_t _upb_Arena_RefCountFromTagged(uintptr_t parent_or_count) {
+  UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count));
+  return parent_or_count >> 1;
+}
+
+UPB_INLINE uintptr_t _upb_Arena_TaggedFromRefcount(uint32_t refcount) {
+  uintptr_t parent_or_count = (((uintptr_t)refcount) << 1) | 1;
+  UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count));
+  return parent_or_count;
+}
+
+UPB_INLINE upb_Arena* _upb_Arena_PointerFromTagged(uintptr_t parent_or_count) {
+  UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count));
+  return (upb_Arena*)parent_or_count;
+}
+
+UPB_INLINE uintptr_t _upb_Arena_TaggedFromPointer(upb_Arena* a) {
+  uintptr_t parent_or_count = (uintptr_t)a;
+  UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count));
+  return parent_or_count;
+}
 
 
 #endif /* UPB_MEM_ARENA_INTERNAL_H_ */
 
+#ifndef UPB_PORT_ATOMIC_H_
+#define UPB_PORT_ATOMIC_H_
+
+
+#ifdef UPB_USE_C11_ATOMICS
+
+#include <stdatomic.h>
+#include <stdbool.h>
+
+UPB_INLINE void upb_Atomic_Init(_Atomic uintptr_t* addr, uintptr_t val) {
+  atomic_init(addr, val);
+}
+
+UPB_INLINE uintptr_t upb_Atomic_LoadAcquire(_Atomic uintptr_t* addr) {
+  return atomic_load_explicit(addr, memory_order_acquire);
+}
+
+UPB_INLINE void upb_Atomic_StoreRelaxed(_Atomic uintptr_t* addr,
+                                        uintptr_t val) {
+  atomic_store_explicit(addr, val, memory_order_relaxed);
+}
+
+UPB_INLINE void upb_Atomic_AddRelease(_Atomic uintptr_t* addr, uintptr_t val) {
+  atomic_fetch_add_explicit(addr, val, memory_order_release);
+}
+
+UPB_INLINE void upb_Atomic_SubRelease(_Atomic uintptr_t* addr, uintptr_t val) {
+  atomic_fetch_sub_explicit(addr, val, memory_order_release);
+}
+
+UPB_INLINE uintptr_t upb_Atomic_ExchangeAcqRel(_Atomic uintptr_t* addr,
+                                               uintptr_t val) {
+  return atomic_exchange_explicit(addr, val, memory_order_acq_rel);
+}
+
+UPB_INLINE bool upb_Atomic_CompareExchangeStrongAcqRel(_Atomic uintptr_t* addr,
+                                                       uintptr_t* expected,
+                                                       uintptr_t desired) {
+  return atomic_compare_exchange_strong_explicit(
+      addr, expected, desired, memory_order_release, memory_order_acquire);
+}
+
+#else  // !UPB_USE_C11_ATOMICS
+
+UPB_INLINE void upb_Atomic_Init(uintptr_t* addr, uintptr_t val) { *addr = val; }
+
+UPB_INLINE uintptr_t upb_Atomic_LoadAcquire(uintptr_t* addr) { return *addr; }
+
+UPB_INLINE void upb_Atomic_StoreRelaxed(uintptr_t* addr, uintptr_t val) {
+  *addr = val;
+}
+
+UPB_INLINE void upb_Atomic_AddRelease(uintptr_t* addr, uintptr_t val) {
+  *addr += val;
+}
+
+UPB_INLINE void upb_Atomic_SubRelease(uintptr_t* addr, uintptr_t val) {
+  *addr -= val;
+}
+
+UPB_INLINE uintptr_t upb_Atomic_ExchangeAcqRel(uintptr_t* addr, uintptr_t val) {
+  uintptr_t ret = *addr;
+  *addr = val;
+  return ret;
+}
+
+UPB_INLINE bool upb_Atomic_CompareExchangeStrongAcqRel(uintptr_t* addr,
+                                                       uintptr_t* expected,
+                                                       uintptr_t desired) {
+  if (*addr == *expected) {
+    *addr = desired;
+    return true;
+  } else {
+    *expected = *addr;
+    return false;
+  }
+}
+
+#endif
+
+
+#endif  // UPB_PORT_ATOMIC_H_
+
 #ifndef UPB_WIRE_READER_H_
 #define UPB_WIRE_READER_H_
 
@@ -9782,17 +9920,6 @@
   return _kUpb_FromBase92[ch - ' '];
 }
 
-UPB_INLINE bool _upb_FieldType_IsPackable(upb_FieldType type) {
-  // clang-format off
-  const unsigned kUnpackableTypes =
-      (1 << kUpb_FieldType_String) |
-      (1 << kUpb_FieldType_Bytes) |
-      (1 << kUpb_FieldType_Message) |
-      (1 << kUpb_FieldType_Group);
-  // clang-format on
-  return (1 << type) & ~kUnpackableTypes;
-}
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
@@ -10790,3 +10917,5 @@
 #undef UPB_DESCRIPTOR_UPB_H_FILENAME
 #undef UPB_DESC
 #undef UPB_IS_GOOGLE3
+#undef UPB_ATOMIC
+#undef UPB_USE_C11_ATOMICS