memory-profiler 1.1.11 → 1.1.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1237585b03f1c87b2c4cafb01668200bc33d518c35f832539315a7f6f37dc4f2
4
- data.tar.gz: 13a79c36183a794df061076e3e09dd2a8a1e14eadfcdb0dc5e3317a6902f622c
3
+ metadata.gz: 4fb4dabaaccdf849f1226fc675a2ffed0893ee3b1298263c40b42667c544f0b4
4
+ data.tar.gz: de34c582331bcd65fa65bda39e41ea5c9fd07ab44fa9c325729011c47f0a5353
5
5
  SHA512:
6
- metadata.gz: 98c104bac6001ec5cde21d984a80a69ac992a113677ea672a81d1d1e468e754331f1170ea58c3a6ba8f1fe4a453ec669d143f7af71ab797e0d206a50bd8bbe8a
7
- data.tar.gz: 2bf799367a7cd59a760f52c89f8da0ab3ee252867bdcca431ca9340349172bcf0962f626f4cada76fcfd721084fb8de8dbe0d8692eb9593a5b4a56f625587436
6
+ metadata.gz: c8b7a4c1c3d3eff6c2ff9531847544bf7b9c8be7008615162b9442726066df94d48ab77ce34d0af106ac1376e14a8ede49ed90be8b2e29818b781c6ac34ae8f3
7
+ data.tar.gz: bdf055ac783a19b8662a271de7b5493c4c7cbac6b01c0c1a515809a04058262ec6d2c42c96a8f2cbef558edf0c28e35fdbcc3f818c4e5e9d2fc7fb6a11d57d1c
checksums.yaml.gz.sig CHANGED
Binary file
@@ -12,8 +12,9 @@ static VALUE Memory_Profiler_Allocations = Qnil;
12
12
 
13
13
  // Helper to mark states table (object => state)
14
14
  static int Memory_Profiler_Allocations_states_mark(st_data_t key, st_data_t value, st_data_t arg) {
15
- // Don't mark the object key (weak reference - don't keep objects alive)
16
- // Mark the state value
15
+ // We don't want the key to move - we can't rehash the table if it does.
16
+ rb_gc_mark((VALUE)key);
17
+
17
18
  VALUE state = (VALUE)value;
18
19
  rb_gc_mark_movable(state);
19
20
  return ST_CONTINUE;
@@ -27,19 +28,7 @@ static int Memory_Profiler_Allocations_states_foreach(st_data_t key, st_data_t v
27
28
 
28
29
  // Replace callback for st_foreach_with_replace to update states during compaction
29
30
  static int Memory_Profiler_Allocations_states_compact(st_data_t *key, st_data_t *value, st_data_t data, int existing) {
30
- // Key is object (VALUE) - we can't update if it moved (would require rehashing/allocation)
31
- VALUE old_state = (VALUE)*value;
32
- VALUE new_state = rb_gc_location(old_state);
33
-
34
- // NOTE: We can't update object keys if they moved (would require rehashing/allocation).
35
- // This means lookups may fail after compaction for moved objects.
36
- // This is acceptable - FREEOBJ will simply not find the state and skip the callback.
37
- // The state will be cleaned up when Allocations is freed/cleared.
38
-
39
- // Update state value if it moved (this is safe, doesn't rehash)
40
- if (old_state != new_state) {
41
- *value = (st_data_t)new_state;
42
- }
31
+ *value = (st_data_t)rb_gc_location((VALUE)*value);
43
32
 
44
33
  return ST_CONTINUE;
45
34
  }
@@ -302,10 +302,18 @@ static void Memory_Profiler_Capture_event_callback(VALUE data, void *ptr) {
302
302
  // Skip NEWOBJ if disabled (during callback) to prevent infinite recursion
303
303
  if (capture->paused) return;
304
304
 
305
+ // It's safe to unconditionally call here:
306
+ object = rb_obj_id(object);
307
+
305
308
  Memory_Profiler_Events_enqueue(MEMORY_PROFILER_EVENT_TYPE_NEWOBJ, data, klass, object);
306
309
  } else if (event_flag == RUBY_INTERNAL_EVENT_FREEOBJ) {
307
- // Always process FREEOBJ to ensure state cleanup
308
- Memory_Profiler_Events_enqueue(MEMORY_PROFILER_EVENT_TYPE_FREEOBJ, data, klass, object);
310
+ // We only care about objects that have been seen before (i.e. have an object ID):
311
+ if (RB_FL_TEST(object, FL_SEEN_OBJ_ID)) {
312
+ // It's only safe to call here if the object already has an object ID.
313
+ object = rb_obj_id(object);
314
+
315
+ Memory_Profiler_Events_enqueue(MEMORY_PROFILER_EVENT_TYPE_FREEOBJ, data, klass, object);
316
+ }
309
317
  }
310
318
  }
311
319
 
@@ -136,12 +136,7 @@ static void Memory_Profiler_Events_compact_queue(struct Memory_Profiler_Queue *q
136
136
  // Update all VALUEs if they moved during compaction:
137
137
  event->capture = rb_gc_location(event->capture);
138
138
  event->klass = rb_gc_location(event->klass);
139
-
140
- // For NEWOBJ: update object pointer if it moved
141
- // For FREEOBJ: DON'T update (object is being freed, pointer is stale)
142
- if (event->type == MEMORY_PROFILER_EVENT_TYPE_NEWOBJ) {
143
- event->object = rb_gc_location(event->object);
144
- }
139
+ event->object = rb_gc_location(event->object);
145
140
  }
146
141
  }
147
142
 
@@ -7,7 +7,7 @@
7
7
  module Memory
8
8
  # @namespace
9
9
  module Profiler
10
- VERSION = "1.1.11"
10
+ VERSION = "1.1.12"
11
11
  end
12
12
  end
13
13
 
data/readme.md CHANGED
@@ -22,6 +22,10 @@ Please see the [project documentation](https://socketry.github.io/memory-profile
22
22
 
23
23
  Please see the [project releases](https://socketry.github.io/memory-profiler/releases/index) for all releases.
24
24
 
25
+ ### v1.1.12
26
+
27
+ - Use `rb_obj_id` for tracking object states to avoid compaction issues.
28
+
25
29
  ### v1.1.11
26
30
 
27
31
  - Double buffer shared events queues to fix queue corruption.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v1.1.12
4
+
5
+ - Use `rb_obj_id` for tracking object states to avoid compaction issues.
6
+
3
7
  ## v1.1.11
4
8
 
5
9
  - Double buffer shared events queues to fix queue corruption.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memory-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.11
4
+ version: 1.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file