google-protobuf 3.15.2 → 3.15.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adbba3c7159278b9926b5dbf75a5d76030695ae716122593d756b12d4e30f70d
4
- data.tar.gz: ea8bc4279e712286fa3d3a18649f847a0717031c5295f261a2f7846dfb9e5c69
3
+ metadata.gz: 46075d9778b236e0f1e75e03e1a9c6da3204864dceea47df28fdf1173eec0e00
4
+ data.tar.gz: f2df957ec73d41fb5a3ba7c39e4bd955a972898342e37988fdcf751e863e50cd
5
5
  SHA512:
6
- metadata.gz: 3f5c170a07539388568608d9e97285ed1985057cb342c5a63a8e827e6946b0bc1d446ebdd27aba08d11ded7813a93bb0bebc5205122226ea2b8dcd6cb4fba7d0
7
- data.tar.gz: '084b27c355258972a8f2b1a839d3580a93d45bfd564730d1afebd50ae2238ef6e00035557f6545f6fcd33f9ef4ab1690aa8e0ade9ecdccf2028991dab6b8cb3c'
6
+ metadata.gz: 4fa77308872b2278593e036da2d896b13560b2c8c5ca2e297bdcd281480f4343b91f8ffa34f4f267cf81ec6feeee3c6b6ad9b02cc7bf96cda0e2f6c47e4cee72
7
+ data.tar.gz: b365ff4f17e7e0ddeb4cb9f3cb17dc5aeece254d21754262af96584569fe8e3a39fd7b07fd3fd8b6e7fe93487eafd1c45b1272cacbb9d673870bb312260a8835
@@ -295,7 +295,7 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
295
295
 
296
296
  self->def_to_descriptor = rb_hash_new();
297
297
  self->symtab = upb_symtab_new();
298
- ObjectCache_Add(self->symtab, ret, _upb_symtab_arena(self->symtab));
298
+ ObjectCache_Add(self->symtab, ret);
299
299
 
300
300
  return ret;
301
301
  }
@@ -93,7 +93,7 @@ VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type,
93
93
  if (val == Qnil) {
94
94
  val = Map_alloc(cMap);
95
95
  Map* self;
96
- ObjectCache_Add(map, val, Arena_get(arena));
96
+ ObjectCache_Add(map, val);
97
97
  TypedData_Get_Struct(val, Map, &Map_type, self);
98
98
  self->map = map;
99
99
  self->arena = arena;
@@ -318,7 +318,7 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
318
318
 
319
319
  self->map = upb_map_new(Arena_get(self->arena), self->key_type,
320
320
  self->value_type_info.type);
321
- ObjectCache_Add(self->map, _self, Arena_get(self->arena));
321
+ ObjectCache_Add(self->map, _self);
322
322
 
323
323
  if (init_arg != Qnil) {
324
324
  Map_merge_into_self(_self, init_arg);
@@ -590,9 +590,10 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
590
590
  */
591
591
  static VALUE Map_freeze(VALUE _self) {
592
592
  Map* self = ruby_to_Map(_self);
593
-
594
- ObjectCache_Pin(self->map, _self, Arena_get(self->arena));
595
- RB_OBJ_FREEZE(_self);
593
+ if (!RB_OBJ_FROZEN(_self)) {
594
+ Arena_Pin(self->arena, _self);
595
+ RB_OBJ_FREEZE(_self);
596
+ }
596
597
  return _self;
597
598
  }
598
599
 
@@ -105,7 +105,7 @@ void Message_InitPtr(VALUE self_, upb_msg *msg, VALUE arena) {
105
105
  Message* self = ruby_to_Message(self_);
106
106
  self->msg = msg;
107
107
  self->arena = arena;
108
- ObjectCache_Add(msg, self_, Arena_get(arena));
108
+ ObjectCache_Add(msg, self_);
109
109
  }
110
110
 
111
111
  VALUE Message_GetArena(VALUE msg_rb) {
@@ -855,8 +855,10 @@ static VALUE Message_to_h(VALUE _self) {
855
855
  */
856
856
  static VALUE Message_freeze(VALUE _self) {
857
857
  Message* self = ruby_to_Message(_self);
858
- ObjectCache_Pin(self->msg, _self, Arena_get(self->arena));
859
- RB_OBJ_FREEZE(_self);
858
+ if (!RB_OBJ_FROZEN(_self)) {
859
+ Arena_Pin(self->arena, _self);
860
+ RB_OBJ_FREEZE(_self);
861
+ }
860
862
  return _self;
861
863
  }
862
864
 
@@ -167,30 +167,55 @@ void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val,
167
167
  // Arena
168
168
  // -----------------------------------------------------------------------------
169
169
 
170
- void Arena_free(void* data) { upb_arena_free(data); }
170
+ typedef struct {
171
+ upb_arena *arena;
172
+ VALUE pinned_objs;
173
+ } Arena;
174
+
175
+ static void Arena_mark(void *data) {
176
+ Arena *arena = data;
177
+ rb_gc_mark(arena->pinned_objs);
178
+ }
179
+
180
+ static void Arena_free(void *data) {
181
+ Arena *arena = data;
182
+ upb_arena_free(arena->arena);
183
+ }
171
184
 
172
185
  static VALUE cArena;
173
186
 
174
187
  const rb_data_type_t Arena_type = {
175
188
  "Google::Protobuf::Internal::Arena",
176
- { NULL, Arena_free, NULL },
189
+ { Arena_mark, Arena_free, NULL },
190
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
177
191
  };
178
192
 
179
193
  static VALUE Arena_alloc(VALUE klass) {
180
- upb_arena *arena = upb_arena_new();
194
+ Arena *arena = ALLOC(Arena);
195
+ arena->arena = upb_arena_new();
196
+ arena->pinned_objs = Qnil;
181
197
  return TypedData_Wrap_Struct(klass, &Arena_type, arena);
182
198
  }
183
199
 
184
200
  upb_arena *Arena_get(VALUE _arena) {
185
- upb_arena *arena;
186
- TypedData_Get_Struct(_arena, upb_arena, &Arena_type, arena);
187
- return arena;
201
+ Arena *arena;
202
+ TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
203
+ return arena->arena;
188
204
  }
189
205
 
190
206
  VALUE Arena_new() {
191
207
  return Arena_alloc(cArena);
192
208
  }
193
209
 
210
+ void Arena_Pin(VALUE _arena, VALUE obj) {
211
+ Arena *arena;
212
+ TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
213
+ if (arena->pinned_objs == Qnil) {
214
+ arena->pinned_objs = rb_ary_new();
215
+ }
216
+ rb_ary_push(arena->pinned_objs, obj);
217
+ }
218
+
194
219
  void Arena_register(VALUE module) {
195
220
  VALUE internal = rb_define_module_under(module, "Internal");
196
221
  VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject);
@@ -209,122 +234,79 @@ void Arena_register(VALUE module) {
209
234
  // different wrapper objects for the same C object, which saves memory and
210
235
  // preserves object identity.
211
236
  //
212
- // We use Hash and/or WeakMap for the cache. WeakMap is faster overall
213
- // (probably due to removal being integrated with GC) but doesn't work for Ruby
214
- // <2.7 (see note below). We need Hash for Ruby <2.7 and for cases where we
215
- // need to GC-root the object (notably when the object has been frozen).
237
+ // We use WeakMap for the cache. For Ruby <2.7 we also need a secondary Hash
238
+ // to store WeakMap keys because Ruby <2.7 WeakMap doesn't allow non-finalizable
239
+ // keys.
216
240
 
217
241
  #if RUBY_API_VERSION_CODE >= 20700
218
- #define USE_WEAK_MAP 1
242
+ #define USE_SECONDARY_MAP 0
219
243
  #else
220
- #define USE_WEAK_MAP 0
244
+ #define USE_SECONDARY_MAP 1
221
245
  #endif
222
246
 
223
- static VALUE ObjectCache_GetKey(const void* key) {
224
- char buf[sizeof(key)];
225
- memcpy(&buf, &key, sizeof(key));
226
- intptr_t key_int = (intptr_t)key;
227
- PBRUBY_ASSERT((key_int & 3) == 0);
228
- return LL2NUM(key_int >> 2);
229
- }
247
+ #if USE_SECONDARY_MAP
230
248
 
231
- // Strong object cache, uses regular Hash and GC-roots objects.
232
- // - For Ruby <2.7, used for all objects.
233
- // - For Ruby >=2.7, used only for frozen objects, so we preserve the "frozen"
234
- // bit (since this information is not preserved at the upb level).
249
+ // Maps Numeric -> Object. The object is then used as a key into the WeakMap.
250
+ // This is needed for Ruby <2.7 where a number cannot be a key to WeakMap.
251
+ // The object is used only for its identity; it does not contain any data.
252
+ VALUE secondary_map = Qnil;
235
253
 
236
- VALUE strong_obj_cache = Qnil;
237
-
238
- static void StrongObjectCache_Init() {
239
- rb_gc_register_address(&strong_obj_cache);
240
- strong_obj_cache = rb_hash_new();
254
+ static void SecondaryMap_Init() {
255
+ rb_gc_register_address(&secondary_map);
256
+ secondary_map = rb_hash_new();
241
257
  }
242
258
 
243
- static void StrongObjectCache_Remove(void* key) {
244
- VALUE key_rb = ObjectCache_GetKey(key);
245
- PBRUBY_ASSERT(rb_hash_lookup(strong_obj_cache, key_rb) != Qnil);
246
- rb_hash_delete(strong_obj_cache, key_rb);
259
+ static VALUE SecondaryMap_Get(VALUE key) {
260
+ VALUE ret = rb_hash_lookup(secondary_map, key);
261
+ if (ret == Qnil) {
262
+ ret = rb_eval_string("Object.new");
263
+ rb_hash_aset(secondary_map, key, ret);
264
+ }
265
+ return ret;
247
266
  }
248
267
 
249
- static VALUE StrongObjectCache_Get(const void* key) {
250
- VALUE key_rb = ObjectCache_GetKey(key);
251
- return rb_hash_lookup(strong_obj_cache, key_rb);
252
- }
268
+ #endif
253
269
 
254
- static void StrongObjectCache_Add(const void* key, VALUE val,
255
- upb_arena* arena) {
256
- PBRUBY_ASSERT(StrongObjectCache_Get(key) == Qnil);
257
- VALUE key_rb = ObjectCache_GetKey(key);
258
- rb_hash_aset(strong_obj_cache, key_rb, val);
259
- upb_arena_addcleanup(arena, (void*)key, StrongObjectCache_Remove);
270
+ static VALUE ObjectCache_GetKey(const void* key) {
271
+ char buf[sizeof(key)];
272
+ memcpy(&buf, &key, sizeof(key));
273
+ intptr_t key_int = (intptr_t)key;
274
+ PBRUBY_ASSERT((key_int & 3) == 0);
275
+ VALUE ret = LL2NUM(key_int >> 2);
276
+ #if USE_SECONDARY_MAP
277
+ ret = SecondaryMap_Get(ret);
278
+ #endif
279
+ return ret;
260
280
  }
261
281
 
262
- // Weak object cache. This speeds up the test suite significantly, so we
263
- // presume it speeds up real code also. However we can only use it in Ruby
264
- // >=2.7 due to:
265
- // https://bugs.ruby-lang.org/issues/16035
266
-
267
- #if USE_WEAK_MAP
282
+ // Public ObjectCache API.
268
283
 
269
284
  VALUE weak_obj_cache = Qnil;
285
+ ID item_get;
286
+ ID item_set;
270
287
 
271
- static void WeakObjectCache_Init() {
288
+ static void ObjectCache_Init() {
272
289
  rb_gc_register_address(&weak_obj_cache);
273
290
  VALUE klass = rb_eval_string("ObjectSpace::WeakMap");
274
291
  weak_obj_cache = rb_class_new_instance(0, NULL, klass);
275
- }
276
-
277
- static VALUE WeakObjectCache_Get(const void* key) {
278
- VALUE key_rb = ObjectCache_GetKey(key);
279
- VALUE ret = rb_funcall(weak_obj_cache, rb_intern("[]"), 1, key_rb);
280
- return ret;
281
- }
282
-
283
- static void WeakObjectCache_Add(const void* key, VALUE val) {
284
- PBRUBY_ASSERT(WeakObjectCache_Get(key) == Qnil);
285
- VALUE key_rb = ObjectCache_GetKey(key);
286
- rb_funcall(weak_obj_cache, rb_intern("[]="), 2, key_rb, val);
287
- PBRUBY_ASSERT(WeakObjectCache_Get(key) == val);
288
- }
289
-
290
- #endif
291
-
292
- // Public ObjectCache API.
293
-
294
- static void ObjectCache_Init() {
295
- StrongObjectCache_Init();
296
- #if USE_WEAK_MAP
297
- WeakObjectCache_Init();
292
+ item_get = rb_intern("[]");
293
+ item_set = rb_intern("[]=");
294
+ #if USE_SECONDARY_MAP
295
+ SecondaryMap_Init();
298
296
  #endif
299
297
  }
300
298
 
301
- void ObjectCache_Add(const void* key, VALUE val, upb_arena *arena) {
302
- #if USE_WEAK_MAP
303
- (void)arena;
304
- WeakObjectCache_Add(key, val);
305
- #else
306
- StrongObjectCache_Add(key, val, arena);
307
- #endif
299
+ void ObjectCache_Add(const void* key, VALUE val) {
300
+ PBRUBY_ASSERT(ObjectCache_Get(key) == Qnil);
301
+ VALUE key_rb = ObjectCache_GetKey(key);
302
+ rb_funcall(weak_obj_cache, item_set, 2, key_rb, val);
303
+ PBRUBY_ASSERT(ObjectCache_Get(key) == val);
308
304
  }
309
305
 
310
306
  // Returns the cached object for this key, if any. Otherwise returns Qnil.
311
307
  VALUE ObjectCache_Get(const void* key) {
312
- #if USE_WEAK_MAP
313
- return WeakObjectCache_Get(key);
314
- #else
315
- return StrongObjectCache_Get(key);
316
- #endif
317
- }
318
-
319
- void ObjectCache_Pin(const void* key, VALUE val, upb_arena *arena) {
320
- #if USE_WEAK_MAP
321
- PBRUBY_ASSERT(WeakObjectCache_Get(key) == val);
322
- // This will GC-root the object, but we'll still use the weak map for
323
- // actual lookup.
324
- StrongObjectCache_Add(key, val, arena);
325
- #else
326
- // Value is already pinned, nothing to do.
327
- #endif
308
+ VALUE key_rb = ObjectCache_GetKey(key);
309
+ return rb_funcall(weak_obj_cache, item_get, 1, key_rb);
328
310
  }
329
311
 
330
312
  /*
@@ -55,6 +55,13 @@ const upb_fielddef* map_field_value(const upb_fielddef* field);
55
55
  VALUE Arena_new();
56
56
  upb_arena *Arena_get(VALUE arena);
57
57
 
58
+ // Pins this Ruby object to the lifetime of this arena, so that as long as the
59
+ // arena is alive this object will not be collected.
60
+ //
61
+ // We use this to guarantee that the "frozen" bit on the object will be
62
+ // remembered, even if the user drops their reference to this precise object.
63
+ void Arena_Pin(VALUE arena, VALUE obj);
64
+
58
65
  // -----------------------------------------------------------------------------
59
66
  // ObjectCache
60
67
  // -----------------------------------------------------------------------------
@@ -68,19 +75,11 @@ upb_arena *Arena_get(VALUE arena);
68
75
  // Adds an entry to the cache. The "arena" parameter must give the arena that
69
76
  // "key" was allocated from. In Ruby <2.7.0, it will be used to remove the key
70
77
  // from the cache when the arena is destroyed.
71
- void ObjectCache_Add(const void* key, VALUE val, upb_arena *arena);
78
+ void ObjectCache_Add(const void* key, VALUE val);
72
79
 
73
80
  // Returns the cached object for this key, if any. Otherwise returns Qnil.
74
81
  VALUE ObjectCache_Get(const void* key);
75
82
 
76
- // Pins the previously added object so it is GC-rooted. This turns the
77
- // reference to "val" from weak to strong. We use this to guarantee that the
78
- // "frozen" bit on the object will be remembered, even if the user drops their
79
- // reference to this precise object.
80
- //
81
- // The "arena" parameter must give the arena that "key" was allocated from.
82
- void ObjectCache_Pin(const void* key, VALUE val, upb_arena *arena);
83
-
84
83
  // -----------------------------------------------------------------------------
85
84
  // StringBuilder, for inspect
86
85
  // -----------------------------------------------------------------------------
@@ -88,7 +88,7 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info,
88
88
  if (val == Qnil) {
89
89
  val = RepeatedField_alloc(cRepeatedField);
90
90
  RepeatedField* self;
91
- ObjectCache_Add(array, val, Arena_get(arena));
91
+ ObjectCache_Add(array, val);
92
92
  TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
93
93
  self->array = array;
94
94
  self->arena = arena;
@@ -500,9 +500,10 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
500
500
  */
501
501
  static VALUE RepeatedField_freeze(VALUE _self) {
502
502
  RepeatedField* self = ruby_to_RepeatedField(_self);
503
-
504
- ObjectCache_Pin(self->array, _self, Arena_get(self->arena));
505
- RB_OBJ_FREEZE(_self);
503
+ if (!RB_OBJ_FROZEN(_self)) {
504
+ Arena_Pin(self->arena, _self);
505
+ RB_OBJ_FREEZE(_self);
506
+ }
506
507
  return _self;
507
508
  }
508
509
 
@@ -610,7 +611,7 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
610
611
 
611
612
  self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
612
613
  self->array = upb_array_new(arena, self->type_info.type);
613
- ObjectCache_Add(self->array, _self, arena);
614
+ ObjectCache_Add(self->array, _self);
614
615
 
615
616
  if (ary != Qnil) {
616
617
  if (!RB_TYPE_P(ary, T_ARRAY)) {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-protobuf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.15.2
4
+ version: 3.15.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Protobuf Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-23 00:00:00.000000000 Z
11
+ date: 2021-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler-dock
@@ -123,7 +123,7 @@ homepage: https://developers.google.com/protocol-buffers
123
123
  licenses:
124
124
  - BSD-3-Clause
125
125
  metadata:
126
- source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.15.2/ruby
126
+ source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.15.3/ruby
127
127
  post_install_message:
128
128
  rdoc_options: []
129
129
  require_paths: