Project

General

Profile

Feature #11599 ยป objspace_dump.patch

yosiat (Yosi Attias), 10/19/2015 06:49 PM

View differences:

ChangeLog
22 22
	  merging load_file_internal and load_file_internal2, and remove
23 23
	  nested rb_protect and rb_ensure.
24 24

  
25
Sat Oct 17 08:47:41 2015  Yosi Attias  <yosy101@gmail.com>
26

  
27
	* ext/objspace/objspace_dump.c(dump_object): Dump entries of hash - the key & values.
28
	* test/objspace/test_objspace.rb: Adding test for the entires - test_dump_entries_empty_hash and test_dump_entries_hash
29

  
25 30
Sat Oct 17 05:28:32 2015  Rei Odaira  <Rei.Odaira@gmail.com>
26 31

  
27 32
	* test/ruby/test_symbol.rb (test_symbol_fstr_leak): add a warm-up
ext/objspace/objspace_dump.c
125 125
    return "UNKNOWN";
126 126
}
127 127

  
128
struct hash_keys_iter {
129
  struct dump_config *dc;
130
  int cur_i;
131
};
132

  
133
static void
134
dump_variable_value(struct dump_config *dc, VALUE value)
135
{
136
  if(!SPECIAL_CONST_P(value)) {
137
    dump_append(dc, "\"%p\"", (void *)value);
138
  } else {
139
    dump_append_string_value(dc, rb_obj_as_string(rb_funcallv(value, idTo_s, 0, 0)));
140
  }
141
}
142

  
143

  
144
static int
145
hash_entries_iter(VALUE key, VALUE value, VALUE arg)
146
{
147
  struct hash_keys_iter *keys_iter = (struct hash_keys_iter *)arg;
148
  if(keys_iter->cur_i > 0) {
149
    dump_append(keys_iter->dc, ",");
150
  }
151

  
152
  dump_append(keys_iter->dc, "{");
153

  
154
  dump_append(keys_iter->dc, "\"key\":");
155
  dump_variable_value(keys_iter->dc, key);
156
  dump_append(keys_iter->dc, ",");
157

  
158
  dump_append(keys_iter->dc, "\"value\":");
159
  dump_variable_value(keys_iter->dc, value);
160

  
161
  dump_append(keys_iter->dc, "}");
162

  
163
  keys_iter->cur_i++;
164
  return ST_CONTINUE;
165
}
166

  
167
static void
168
dump_hash_entries(struct dump_config *dc, VALUE hash)
169
{
170
  if(RHASH_SIZE(hash) == 0) {
171
    dump_append(dc, ", \"entries\": []");
172
  } else {
173

  
174
    struct hash_keys_iter arg;
175
    arg.dc = dc;
176
    arg.cur_i = 0;
177

  
178

  
179
    dump_append(dc, ", \"entries\": [");
180
    rb_hash_foreach(hash, hash_entries_iter, (VALUE)&arg);
181
    dump_append(dc, "]");
182
  }
183
}
184

  
185

  
128 186
static void
129 187
reachable_object_i(VALUE ref, void *data)
130 188
{
......
200 258

  
201 259
      case T_HASH:
202 260
	dump_append(dc, ", \"size\":%ld", RHASH_SIZE(obj));
261
	dump_hash_entries(dc, obj);
203 262
	if (FL_TEST(obj, HASH_PROC_DEFAULT))
204 263
	    dump_append(dc, ", \"default\":\"%p\"", (void *)RHASH_IFNONE(obj));
205 264
	break;
test/objspace/test_objspace.rb
1 1
require "test/unit"
2 2
require "objspace"
3
require "json"
3 4

  
4 5
class TestObjSpace < Test::Unit::TestCase
5 6
  def test_memsize_of
......
253 254
    assert_match /"method":"#{loc.base_label}"/, info
254 255
  end
255 256

  
257
  def test_dump_entries_empty_hash
258
    dumped_hash = JSON.parse(ObjectSpace.dump({}))
259
    assert_equal [], dumped_hash["entries"]
260
  end
261

  
262
  def test_dump_entries_hash
263
    # freeze the string, so we will use the same string in the hash..
264
    str_key = "Hello world".freeze
265
    hash = {}
266
    hash[:a] = 1
267
    hash[str_key] = -1
268

  
269
    str_key_d = JSON.parse(ObjectSpace.dump(str_key))
270
    dumped_hash = JSON.parse(ObjectSpace.dump(hash))
271

  
272

  
273
    # make sure we have two entries
274
    assert_equal 2, dumped_hash["entries"].length
275

  
276
    # check the first entry
277
    first_entry = dumped_hash["entries"][0]
278
    assert_equal "a", first_entry["key"]
279
    assert_equal "1", first_entry["value"]
280

  
281
    # check the second entry
282
    second_entry = dumped_hash["entries"][1]
283
    assert_equal str_key_d["address"], second_entry["key"]
284
    assert_equal "-1", second_entry["value"]
285
  end
286

  
256 287
  def test_dump_special_consts
257 288
    # [ruby-core:69692] [Bug #11291]
258 289
    assert_equal('{}', ObjectSpace.dump(nil))