diff --git a/gems/native-tracer/ext/native_tracer/src/lib.rs b/gems/native-tracer/ext/native_tracer/src/lib.rs index fe2d82f..1455a60 100644 --- a/gems/native-tracer/ext/native_tracer/src/lib.rs +++ b/gems/native-tracer/ext/native_tracer/src/lib.rs @@ -84,7 +84,7 @@ struct Recorder { inst_meth_id: ID, parameters_id: ID, class_id: ID, - struct_types: HashMap, + struct_type_versions: HashMap, } fn value_type_id(val: &ValueRecord) -> runtime_tracing::TypeId { @@ -119,26 +119,26 @@ unsafe fn struct_value( vals.push(to_value(recorder, *v, depth - 1, to_s_id)); } - let type_id = if let Some(id) = recorder.struct_types.get(class_name) { - *id - } else { - let field_types: Vec = field_names - .iter() - .zip(&vals) - .map(|(n, v)| FieldTypeRecord { - name: (*n).to_string(), - type_id: value_type_id(v), - }) - .collect(); - let typ = TypeRecord { - kind: TypeKind::Struct, - lang_type: class_name.to_string(), - specific_info: TypeSpecificInfo::Struct { fields: field_types }, - }; - let id = recorder.tracer.ensure_raw_type_id(typ); - recorder.struct_types.insert(class_name.to_string(), id); - id + let version_entry = recorder + .struct_type_versions + .entry(class_name.to_string()) + .or_insert(0); + let name_version = format!("{} (#{})", class_name, *version_entry); + *version_entry += 1; + let field_types: Vec = field_names + .iter() + .zip(&vals) + .map(|(n, v)| FieldTypeRecord { + name: (*n).to_string(), + type_id: value_type_id(v), + }) + .collect(); + let typ = TypeRecord { + kind: TypeKind::Struct, + lang_type: name_version, + specific_info: TypeSpecificInfo::Struct { fields: field_types }, }; + let type_id = recorder.tracer.ensure_raw_type_id(typ); ValueRecord::Struct { field_values: vals, @@ -197,7 +197,7 @@ unsafe extern "C" fn ruby_recorder_alloc(klass: VALUE) -> VALUE { inst_meth_id, parameters_id, class_id, - struct_types: HashMap::new(), + struct_type_versions: HashMap::new(), }); let ty = std::ptr::addr_of!(RECORDER_TYPE) as *const rb_data_type_t; rb_data_typed_object_wrap(klass, Box::into_raw(recorder) as *mut c_void, ty) @@ -577,7 +577,13 @@ unsafe extern "C" fn event_hook_raw(data: VALUE, arg: *mut rb_trace_arg_t) { String::from_utf8_lossy(std::slice::from_raw_parts(ptr as *const u8, len)).to_string() }; let line = rb_num2long(line_val) as i64; - if path.contains("native_trace.rb") { + if path.contains("native_trace.rb") + || path.contains("lib/ruby") + || path.contains("recorder.rb") + || path.contains("trace.rb") + || path.contains("gems/") + || path.starts_with("(o) { defined?(Set) && o.is_a?(Set) } if v.size > MAX_COUNT NOT_SUPPORTED_VALUE else @@ -414,7 +414,7 @@ def to_value(v, depth=10) struct_value('Regexp', ['source', 'options'], [v.source, v.options], depth) when Struct struct_value(v.class.name, v.members.map(&:to_s), v.values, depth) - when defined?(OpenStruct) && v.is_a?(OpenStruct) + when ->(o) { defined?(OpenStruct) && o.is_a?(OpenStruct) } h = v.to_h pairs = h.map do |k, val| struct_value('Pair', ['k', 'v'], [k, val], depth) diff --git a/test/fixtures/more_types_trace.json b/test/fixtures/more_types_trace.json index 3504166..4baa83e 100644 --- a/test/fixtures/more_types_trace.json +++ b/test/fixtures/more_types_trace.json @@ -157,5 +157,378 @@ "kind": "None" } } + }, + { + "Type": { + "kind": 6, + "lang_type": "Pair (#0)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "k", + "type_id": 3 + }, + { + "name": "v", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Pair (#1)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "k", + "type_id": 3 + }, + { + "name": "v", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 0, + "lang_type": "Hash", + "specific_info": { + "kind": "None" + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Range (#0)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "begin", + "type_id": 0 + }, + { + "name": "end", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 0, + "lang_type": "Set", + "specific_info": { + "kind": "None" + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Time (#0)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "sec", + "type_id": 0 + }, + { + "name": "nsec", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Regexp (#0)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "source", + "type_id": 1 + }, + { + "name": "options", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Point (#0)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "x", + "type_id": 0 + }, + { + "name": "y", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Pair (#2)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "k", + "type_id": 3 + }, + { + "name": "v", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 6, + "lang_type": "Pair (#3)", + "specific_info": { + "kind": "Struct", + "fields": [ + { + "name": "k", + "type_id": 3 + }, + { + "name": "v", + "type_id": 0 + } + ] + } + } + }, + { + "Type": { + "kind": 0, + "lang_type": "Array", + "specific_info": { + "kind": "None" + } + } + }, + { + "Value": { + "variable_id": 0, + "value": { + "kind": "Sequence", + "type_id": 16, + "elements": [ + { + "kind": "Float", + "type_id": 5, + "f": 1.5 + }, + { + "kind": "Sequence", + "type_id": 8, + "elements": [ + { + "kind": "Struct", + "type_id": 6, + "field_values": [ + { + "kind": "String", + "type_id": 3, + "text": "a" + }, + { + "kind": "Int", + "type_id": 0, + "i": 1 + } + ] + }, + { + "kind": "Struct", + "type_id": 7, + "field_values": [ + { + "kind": "String", + "type_id": 3, + "text": "b" + }, + { + "kind": "Int", + "type_id": 0, + "i": 2 + } + ] + } + ], + "is_slice": false + }, + { + "kind": "Struct", + "type_id": 9, + "field_values": [ + { + "kind": "Int", + "type_id": 0, + "i": 1 + }, + { + "kind": "Int", + "type_id": 0, + "i": 3 + } + ] + }, + { + "kind": "Sequence", + "type_id": 10, + "elements": [ + { + "kind": "Int", + "type_id": 0, + "i": 1 + }, + { + "kind": "Int", + "type_id": 0, + "i": 2 + }, + { + "kind": "Int", + "type_id": 0, + "i": 3 + } + ], + "is_slice": false + }, + { + "kind": "Struct", + "type_id": 11, + "field_values": [ + { + "kind": "Int", + "type_id": 0, + "i": 0 + }, + { + "kind": "Int", + "type_id": 0, + "i": 0 + } + ] + }, + { + "kind": "Struct", + "type_id": 12, + "field_values": [ + { + "kind": "String", + "type_id": 1, + "text": "ab" + }, + { + "kind": "Int", + "type_id": 0, + "i": 0 + } + ] + }, + { + "kind": "Struct", + "type_id": 13, + "field_values": [ + { + "kind": "Int", + "type_id": 0, + "i": 5 + }, + { + "kind": "Int", + "type_id": 0, + "i": 6 + } + ] + }, + { + "kind": "Sequence", + "type_id": 8, + "elements": [ + { + "kind": "Struct", + "type_id": 14, + "field_values": [ + { + "kind": "String", + "type_id": 3, + "text": "foo" + }, + { + "kind": "Int", + "type_id": 0, + "i": 7 + } + ] + }, + { + "kind": "Struct", + "type_id": 15, + "field_values": [ + { + "kind": "String", + "type_id": 3, + "text": "bar" + }, + { + "kind": "Int", + "type_id": 0, + "i": 8 + } + ] + } + ], + "is_slice": false + } + ], + "is_slice": false + } + } + }, + { + "Step": { + "path_id": 1, + "line": 29 + } + }, + { + "Event": { + "kind": 0, + "content": "1.5\n{:a=>1, :b=>2}\n1..3\n#\n1970-01-01 00:00:00 +0000\n(?-mix:ab)\n#\n#", + "metadata": "" + } } ]