Skip to content

Commit b695e2f

Browse files
Use for object states.
1 parent c52754d commit b695e2f

File tree

4 files changed

+19
-23
lines changed

4 files changed

+19
-23
lines changed

ext/memory/profiler/allocations.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ static VALUE Memory_Profiler_Allocations = Qnil;
1212

1313
// Helper to mark states table (object => state)
1414
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+
1718
VALUE state = (VALUE)value;
1819
rb_gc_mark_movable(state);
1920
return ST_CONTINUE;
@@ -27,19 +28,7 @@ static int Memory_Profiler_Allocations_states_foreach(st_data_t key, st_data_t v
2728

2829
// Replace callback for st_foreach_with_replace to update states during compaction
2930
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);
4332

4433
return ST_CONTINUE;
4534
}

ext/memory/profiler/capture.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,18 @@ static void Memory_Profiler_Capture_event_callback(VALUE data, void *ptr) {
302302
// Skip NEWOBJ if disabled (during callback) to prevent infinite recursion
303303
if (capture->paused) return;
304304

305+
// It's safe to unconditionally call here:
306+
object = rb_obj_id(object);
307+
305308
Memory_Profiler_Events_enqueue(MEMORY_PROFILER_EVENT_TYPE_NEWOBJ, data, klass, object);
306309
} 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+
}
309317
}
310318
}
311319

ext/memory/profiler/events.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,7 @@ static void Memory_Profiler_Events_compact_queue(struct Memory_Profiler_Queue *q
136136
// Update all VALUEs if they moved during compaction:
137137
event->capture = rb_gc_location(event->capture);
138138
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);
145140
}
146141
}
147142

releases.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Releases
22

3+
## Unreleased
4+
5+
- Use `rb_obj_id` for tracking object states to avoid compaction issues.
6+
37
## v1.1.11
48

59
- Double buffer shared events queues to fix queue corruption.

0 commit comments

Comments
 (0)