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