google-protobuf 3.15.3-x86-linux → 3.15.8-x86-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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: baa9d45f0c885758e32b6d221977ef378567b0296dd0aa15b5b2e28801a662bd
4
- data.tar.gz: 33c18b9fb8e2de390a19cec01d5f73bbc2b2089dd1bf3a96ead061822007437d
3
+ metadata.gz: f3fd3973c0a9981c2b563b4570fd3811bfed24f8bbd9c9ef8c7e970eb05e71b9
4
+ data.tar.gz: '08b3a332679e002c2556f31929c69b74fcbbcefae427d44d2c6f3c2b282fde50'
5
5
  SHA512:
6
- metadata.gz: 6fee0801f9c427747d0511023a81fa2d6199308178b08e42c4e75af8277263311b4a6057e0fabb4befe97eebae67e04d6e3694cf9ff0e94a2670128d4b3239df
7
- data.tar.gz: 436d37545240010cb2bcc0d5429b2727ba81c161cb95486a5d6a2a40ef09675eee6eb59eb512c4a79fc1fd30ea5bc7f1fc82deb6b9f1cb139e023778fcc15398
6
+ metadata.gz: b3979160a19520ef46451f071b00b7c2923e491d1bac9e04c5115592d88e84cb1c6a7141d71d967bfb1137fd7b89c5b0787584c1602516f33946306de6c9d986
7
+ data.tar.gz: 9888d6e87b4cfa31774c199b863c47a972efc0ef03fa9aff0b4d607da31c52d3775a52252973954a5f2d6ae567193e5e45b22132ed30df039cc8bb66be78d328
@@ -315,7 +315,7 @@ bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info) {
315
315
  return memcmp(&val1, &val2, 8) == 0;
316
316
  case UPB_TYPE_STRING:
317
317
  case UPB_TYPE_BYTES:
318
- return val1.str_val.size != val2.str_val.size ||
318
+ return val1.str_val.size == val2.str_val.size &&
319
319
  memcmp(val1.str_val.data, val2.str_val.data,
320
320
  val1.str_val.size) == 0;
321
321
  case UPB_TYPE_MESSAGE:
@@ -697,16 +697,13 @@ bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) {
697
697
  * field is of a primitive type).
698
698
  */
699
699
  static VALUE Message_eq(VALUE _self, VALUE _other) {
700
- if (TYPE(_self) != TYPE(_other)) {
701
- return Qfalse;
702
- }
700
+ if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse;
703
701
 
704
702
  Message* self = ruby_to_Message(_self);
705
703
  Message* other = ruby_to_Message(_other);
704
+ assert(self->msgdef == other->msgdef);
706
705
 
707
- return Message_Equal(self->msg, other->msg, self->msgdef)
708
- ? Qtrue
709
- : Qfalse;
706
+ return Message_Equal(self->msg, other->msg, self->msgdef) ? Qtrue : Qfalse;
710
707
  }
711
708
 
712
709
  uint64_t Message_Hash(const upb_msg* msg, const upb_msgdef* m, uint64_t seed) {
@@ -1250,7 +1247,9 @@ upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m,
1250
1247
 
1251
1248
  const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m,
1252
1249
  const char* name, upb_arena* arena) {
1253
- if (value == Qnil) return NULL;
1250
+ if (value == Qnil) {
1251
+ rb_raise(cTypeError, "nil message not allowed here.");
1252
+ }
1254
1253
 
1255
1254
  VALUE klass = CLASS_OF(value);
1256
1255
  VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned);
@@ -180,6 +180,7 @@ static void Arena_mark(void *data) {
180
180
  static void Arena_free(void *data) {
181
181
  Arena *arena = data;
182
182
  upb_arena_free(arena->arena);
183
+ xfree(arena);
183
184
  }
184
185
 
185
186
  static VALUE cArena;
@@ -251,14 +252,80 @@ void Arena_register(VALUE module) {
251
252
  // The object is used only for its identity; it does not contain any data.
252
253
  VALUE secondary_map = Qnil;
253
254
 
255
+ // Mutations to the map are under a mutex, because SeconaryMap_MaybeGC()
256
+ // iterates over the map which cannot happen in parallel with insertions, or
257
+ // Ruby will throw:
258
+ // can't add a new key into hash during iteration (RuntimeError)
259
+ VALUE secondary_map_mutex = Qnil;
260
+
261
+ // Lambda that will GC entries from the secondary map that are no longer present
262
+ // in the primary map.
263
+ VALUE gc_secondary_map_lambda = Qnil;
264
+ ID length;
265
+
266
+ extern VALUE weak_obj_cache;
267
+
254
268
  static void SecondaryMap_Init() {
255
269
  rb_gc_register_address(&secondary_map);
270
+ rb_gc_register_address(&gc_secondary_map_lambda);
271
+ rb_gc_register_address(&secondary_map_mutex);
256
272
  secondary_map = rb_hash_new();
273
+ gc_secondary_map_lambda = rb_eval_string(
274
+ "->(secondary, weak) {\n"
275
+ " secondary.delete_if { |k, v| !weak.key?(v) }\n"
276
+ "}\n");
277
+ secondary_map_mutex = rb_mutex_new();
278
+ length = rb_intern("length");
257
279
  }
258
280
 
259
- static VALUE SecondaryMap_Get(VALUE key) {
281
+ // The secondary map is a regular Hash, and will never shrink on its own.
282
+ // The main object cache is a WeakMap that will automatically remove entries
283
+ // when the target object is no longer reachable, but unless we manually
284
+ // remove the corresponding entries from the secondary map, it will grow
285
+ // without bound.
286
+ //
287
+ // To avoid this unbounded growth we periodically remove entries from the
288
+ // secondary map that are no longer present in the WeakMap. The logic of
289
+ // how often to perform this GC is an artbirary tuning parameter that
290
+ // represents a straightforward CPU/memory tradeoff.
291
+ //
292
+ // Requires: secondary_map_mutex is held.
293
+ static void SecondaryMap_MaybeGC() {
294
+ PBRUBY_ASSERT(rb_mutex_locked_p(secondary_map_mutex) == Qtrue);
295
+ size_t weak_len = NUM2ULL(rb_funcall(weak_obj_cache, length, 0));
296
+ size_t secondary_len = RHASH_SIZE(secondary_map);
297
+ if (secondary_len < weak_len) {
298
+ // Logically this case should not be possible: a valid entry cannot exist in
299
+ // the weak table unless there is a corresponding entry in the secondary
300
+ // table. It should *always* be the case that secondary_len >= weak_len.
301
+ //
302
+ // However ObjectSpace::WeakMap#length (and therefore weak_len) is
303
+ // unreliable: it overreports its true length by including non-live objects.
304
+ // However these non-live objects are not yielded in iteration, so we may
305
+ // have previously deleted them from the secondary map in a previous
306
+ // invocation of SecondaryMap_MaybeGC().
307
+ //
308
+ // In this case, we can't measure any waste, so we just return.
309
+ return;
310
+ }
311
+ size_t waste = secondary_len - weak_len;
312
+ // GC if we could remove at least 2000 entries or 20% of the table size
313
+ // (whichever is greater). Since the cost of the GC pass is O(N), we
314
+ // want to make sure that we condition this on overall table size, to
315
+ // avoid O(N^2) CPU costs.
316
+ size_t threshold = PBRUBY_MAX(secondary_len * 0.2, 2000);
317
+ if (waste > threshold) {
318
+ rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2,
319
+ secondary_map, weak_obj_cache);
320
+ }
321
+ }
322
+
323
+ // Requires: secondary_map_mutex is held by this thread iff create == true.
324
+ static VALUE SecondaryMap_Get(VALUE key, bool create) {
325
+ PBRUBY_ASSERT(!create || rb_mutex_locked_p(secondary_map_mutex) == Qtrue);
260
326
  VALUE ret = rb_hash_lookup(secondary_map, key);
261
- if (ret == Qnil) {
327
+ if (ret == Qnil && create) {
328
+ SecondaryMap_MaybeGC();
262
329
  ret = rb_eval_string("Object.new");
263
330
  rb_hash_aset(secondary_map, key, ret);
264
331
  }
@@ -267,14 +334,15 @@ static VALUE SecondaryMap_Get(VALUE key) {
267
334
 
268
335
  #endif
269
336
 
270
- static VALUE ObjectCache_GetKey(const void* key) {
337
+ // Requires: secondary_map_mutex is held by this thread iff create == true.
338
+ static VALUE ObjectCache_GetKey(const void* key, bool create) {
271
339
  char buf[sizeof(key)];
272
340
  memcpy(&buf, &key, sizeof(key));
273
341
  intptr_t key_int = (intptr_t)key;
274
342
  PBRUBY_ASSERT((key_int & 3) == 0);
275
343
  VALUE ret = LL2NUM(key_int >> 2);
276
344
  #if USE_SECONDARY_MAP
277
- ret = SecondaryMap_Get(ret);
345
+ ret = SecondaryMap_Get(ret, create);
278
346
  #endif
279
347
  return ret;
280
348
  }
@@ -298,14 +366,20 @@ static void ObjectCache_Init() {
298
366
 
299
367
  void ObjectCache_Add(const void* key, VALUE val) {
300
368
  PBRUBY_ASSERT(ObjectCache_Get(key) == Qnil);
301
- VALUE key_rb = ObjectCache_GetKey(key);
369
+ #if USE_SECONDARY_MAP
370
+ rb_mutex_lock(secondary_map_mutex);
371
+ #endif
372
+ VALUE key_rb = ObjectCache_GetKey(key, true);
302
373
  rb_funcall(weak_obj_cache, item_set, 2, key_rb, val);
374
+ #if USE_SECONDARY_MAP
375
+ rb_mutex_unlock(secondary_map_mutex);
376
+ #endif
303
377
  PBRUBY_ASSERT(ObjectCache_Get(key) == val);
304
378
  }
305
379
 
306
380
  // Returns the cached object for this key, if any. Otherwise returns Qnil.
307
381
  VALUE ObjectCache_Get(const void* key) {
308
- VALUE key_rb = ObjectCache_GetKey(key);
382
+ VALUE key_rb = ObjectCache_GetKey(key, false);
309
383
  return rb_funcall(weak_obj_cache, item_get, 1, key_rb);
310
384
  }
311
385
 
@@ -106,6 +106,8 @@ extern VALUE cTypeError;
106
106
  #define PBRUBY_ASSERT(expr) assert(expr)
107
107
  #endif
108
108
 
109
+ #define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
110
+
109
111
  #define UPB_UNUSED(var) (void)var
110
112
 
111
113
  #endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
@@ -6663,10 +6663,9 @@ void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
6663
6663
  }
6664
6664
 
6665
6665
  bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
6666
- if (!_upb_array_realloc(arr, arr->len + 1, arena)) {
6666
+ if (!upb_array_resize(arr, arr->len + 1, arena)) {
6667
6667
  return false;
6668
6668
  }
6669
- arr->len++;
6670
6669
  upb_array_set(arr, arr->len - 1, val);
6671
6670
  return true;
6672
6671
  }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/tests/basic.rb CHANGED
@@ -52,10 +52,15 @@ module BasicTest
52
52
 
53
53
  outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Outer").msgclass
54
54
 
55
- outer_proto = outer.new(
55
+ outer.new(
56
56
  inners: []
57
- )
58
- outer_proto['inners'].to_s
57
+ )['inners'].to_s
58
+
59
+ assert_raise Google::Protobuf::TypeError do
60
+ outer.new(
61
+ inners: [nil]
62
+ ).to_s
63
+ end
59
64
  end
60
65
 
61
66
  def test_has_field
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.3
4
+ version: 3.15.8
5
5
  platform: x86-linux
6
6
  authors:
7
7
  - Protobuf Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-25 00:00:00.000000000 Z
11
+ date: 2021-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler-dock
@@ -128,7 +128,7 @@ homepage: https://developers.google.com/protocol-buffers
128
128
  licenses:
129
129
  - BSD-3-Clause
130
130
  metadata:
131
- source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.15.3/ruby
131
+ source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.15.8/ruby
132
132
  post_install_message:
133
133
  rdoc_options: []
134
134
  require_paths: