Project

General

Profile

Feature #11599 ยป objspace_dump_hash_entries.patch

Patch - yosiat (Yosi Attias), 10/17/2015 12:05 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_hash_value(struct dump_config *dc, VALUE value, const char *prefix) {
135
  dump_append(dc, "\"is_%s_address\": %s,", prefix, SPECIAL_CONST_P(value) ? "false" : "true");
136
  dump_append(dc, "\"%s\":", prefix);
137

  
138
  if(!SPECIAL_CONST_P(value)) {
139
    dump_append(dc, "\"%p\"", (void *)value);
140
  } else {
141
    dump_append_string_value(dc, rb_inspect(value));
142
  }
143
}
144

  
145

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

  
154
  dump_append(keys_iter->dc, "{");
155

  
156
  dump_hash_value(keys_iter->dc, key, "key");
157
  dump_append(keys_iter->dc, ",");
158
  dump_hash_value(keys_iter->dc, value, "value");
159
  dump_append(keys_iter->dc, "}");
160

  
161
  keys_iter->cur_i++;
162
  return ST_CONTINUE;
163
}
164

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

  
171
    struct hash_keys_iter arg;
172
    arg.dc = dc;
173
    arg.cur_i = 0;
174

  
175

  
176
    dump_append(dc, ", \"entries\": [");
177
    rb_hash_foreach(hash, hash_entries_iter, (VALUE)&arg);
178
    dump_append(dc, "]");
179
  }
180
}
181

  
182

  
128 183
static void
129 184
reachable_object_i(VALUE ref, void *data)
130 185
{
......
200 255

  
201 256
      case T_HASH:
202 257
	dump_append(dc, ", \"size\":%ld", RHASH_SIZE(obj));
258
	dump_hash_entries(dc, obj);
203 259
	if (FL_TEST(obj, HASH_PROC_DEFAULT))
204 260
	    dump_append(dc, ", \"default\":\"%p\"", (void *)RHASH_IFNONE(obj));
205 261
	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 false, first_entry["is_key_address"]
279
    assert_equal ":a", first_entry["key"]
280

  
281
    assert_equal false, first_entry["is_value_address"]
282
    assert_equal "1", first_entry["value"]
283

  
284
    # check the second entry
285
    second_entry = dumped_hash["entries"][1]
286
    assert_equal true, second_entry["is_key_address"]
287
    assert_equal str_key_d["address"], second_entry["key"]
288

  
289
    assert_equal false, second_entry["is_value_address"]
290
    assert_equal "-1", second_entry["value"]
291
  end
292

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