Project

General

Profile

Feature #11599 » objspace_dump_hash_entries.patch

Patch - yosiat (Yosi Attias), 10/17/2015 12:05 PM

View differences:

ChangeLog
merging load_file_internal and load_file_internal2, and remove
nested rb_protect and rb_ensure.
Sat Oct 17 08:47:41 2015 Yosi Attias <yosy101@gmail.com>
* ext/objspace/objspace_dump.c(dump_object): Dump entries of hash - the key & values.
* test/objspace/test_objspace.rb: Adding test for the entires - test_dump_entries_empty_hash and test_dump_entries_hash
Sat Oct 17 05:28:32 2015 Rei Odaira <Rei.Odaira@gmail.com>
* test/ruby/test_symbol.rb (test_symbol_fstr_leak): add a warm-up
ext/objspace/objspace_dump.c
return "UNKNOWN";
}
struct hash_keys_iter {
struct dump_config *dc;
int cur_i;
};
static void
dump_hash_value(struct dump_config *dc, VALUE value, const char *prefix) {
dump_append(dc, "\"is_%s_address\": %s,", prefix, SPECIAL_CONST_P(value) ? "false" : "true");
dump_append(dc, "\"%s\":", prefix);
if(!SPECIAL_CONST_P(value)) {
dump_append(dc, "\"%p\"", (void *)value);
} else {
dump_append_string_value(dc, rb_inspect(value));
}
}
static int
hash_entries_iter(VALUE key, VALUE value, VALUE arg)
{
struct hash_keys_iter *keys_iter = (struct hash_keys_iter *)arg;
if(keys_iter->cur_i > 0) {
dump_append(keys_iter->dc, ",");
}
dump_append(keys_iter->dc, "{");
dump_hash_value(keys_iter->dc, key, "key");
dump_append(keys_iter->dc, ",");
dump_hash_value(keys_iter->dc, value, "value");
dump_append(keys_iter->dc, "}");
keys_iter->cur_i++;
return ST_CONTINUE;
}
static void
dump_hash_entries(struct dump_config *dc, VALUE hash) {
if(RHASH_SIZE(hash) == 0) {
dump_append(dc, ", \"entries\": []");
} else {
struct hash_keys_iter arg;
arg.dc = dc;
arg.cur_i = 0;
dump_append(dc, ", \"entries\": [");
rb_hash_foreach(hash, hash_entries_iter, (VALUE)&arg);
dump_append(dc, "]");
}
}
static void
reachable_object_i(VALUE ref, void *data)
{
......
case T_HASH:
dump_append(dc, ", \"size\":%ld", RHASH_SIZE(obj));
dump_hash_entries(dc, obj);
if (FL_TEST(obj, HASH_PROC_DEFAULT))
dump_append(dc, ", \"default\":\"%p\"", (void *)RHASH_IFNONE(obj));
break;
test/objspace/test_objspace.rb
require "test/unit"
require "objspace"
require "json"
class TestObjSpace < Test::Unit::TestCase
def test_memsize_of
......
assert_match /"method":"#{loc.base_label}"/, info
end
def test_dump_entries_empty_hash
dumped_hash = JSON.parse(ObjectSpace.dump({}))
assert_equal [], dumped_hash["entries"]
end
def test_dump_entries_hash
# freeze the string, so we will use the same string in the hash..
str_key = "Hello world".freeze
hash = {}
hash[:a] = 1
hash[str_key] = -1
str_key_d = JSON.parse(ObjectSpace.dump(str_key))
dumped_hash = JSON.parse(ObjectSpace.dump(hash))
# make sure we have two entries
assert_equal 2, dumped_hash["entries"].length
# check the first entry
first_entry = dumped_hash["entries"][0]
assert_equal false, first_entry["is_key_address"]
assert_equal ":a", first_entry["key"]
assert_equal false, first_entry["is_value_address"]
assert_equal "1", first_entry["value"]
# check the second entry
second_entry = dumped_hash["entries"][1]
assert_equal true, second_entry["is_key_address"]
assert_equal str_key_d["address"], second_entry["key"]
assert_equal false, second_entry["is_value_address"]
assert_equal "-1", second_entry["value"]
end
def test_dump_special_consts
# [ruby-core:69692] [Bug #11291]
assert_equal('{}', ObjectSpace.dump(nil))
(1-1/2)