Skip to content

Commit 445b72a

Browse files
committed
[GR-19220] Several gems need at least some value for total_allocated_objects (#2292)
PullRequest: truffleruby/2489
2 parents b981115 + c0f1ed4 commit 445b72a

File tree

4 files changed

+56
-46
lines changed

4 files changed

+56
-46
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ Compatibility:
6767
* Implemented the `Time.at` `in:` parameter.
6868
* Implemented `Kernel#raise` `cause` parameter.
6969
* Improved compatibility of `Signal.trap` and `Kernel#trap` (#2287, @chrisseaton).
70+
* Implemented `GC.stat(:total_allocated_objects)` as `0` (#2292, @chrisseaton).
7071

7172
Performance:
7273

doc/user/compatibility.md

+4
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ Additionally, `FPE`, `ILL`, `KILL`, `SEGV`, `STOP`, and `VTALRM` cannot be trapp
157157

158158
When TruffleRuby is run as part of a polyglot application, any signals that are handled by another language become unavailable for TruffleRuby to trap.
159159

160+
### GC statistics
161+
162+
TruffleRuby provides similar `GC.stat` statistics to MRI, but not all statistics are available, and some statistics may be approximations. Use `GC.stat.keys` to see which are provided with real or approximate values. Missing values will return `0`.
163+
160164
## Features with Very Low Performance
161165

162166
### `ObjectSpace`

spec/ruby/core/gc/stat_spec.rb

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
require_relative '../../spec_helper'
22

33
describe "GC.stat" do
4-
it "supports access by key" do
5-
keys = [:heap_free_slots, :total_allocated_objects, :count]
6-
keys.each do |key|
7-
GC.stat(key).should be_kind_of(Integer)
8-
end
9-
end
10-
114
it "returns hash of values" do
125
stat = GC.stat
136
stat.should be_kind_of(Hash)
147
stat.keys.should include(:count)
158
end
169

10+
it "can return a single value" do
11+
GC.stat(:count).should be_kind_of(Integer)
12+
end
13+
1714
it "increases count after GC is run" do
1815
count = GC.stat(:count)
1916
GC.start
@@ -25,4 +22,19 @@
2522
GC.start
2623
GC.stat(:major_gc_count).should > count
2724
end
25+
26+
it "provides some number for count" do
27+
GC.stat(:count).should be_kind_of(Integer)
28+
GC.stat[:count].should be_kind_of(Integer)
29+
end
30+
31+
it "provides some number for heap_free_slots" do
32+
GC.stat(:heap_free_slots).should be_kind_of(Integer)
33+
GC.stat[:heap_free_slots].should be_kind_of(Integer)
34+
end
35+
36+
it "provides some number for total_allocated_objects" do
37+
GC.stat(:total_allocated_objects).should be_kind_of(Integer)
38+
GC.stat[:total_allocated_objects].should be_kind_of(Integer)
39+
end
2840
end

src/main/ruby/truffleruby/core/gc.rb

+32-39
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ def garbage_collect
7575
GC.start
7676
end
7777

78-
def self.stat(option = nil)
79-
time, count, minor_count, major_count, unknown_count, heap, memory_pool_names, memory_pool_info = Primitive.gc_stat()
78+
def self.stat(key = nil)
79+
time, count, minor_count, major_count, unknown_count, heap, memory_pool_names, memory_pool_info = Primitive.gc_stat
8080
used, committed, init, max = heap
8181

82-
# Initialize stat for statistics that come from memory pools, and populate it with some final stats
82+
# Initialize stat for statistics that come from memory pools, and populate it with some final stats (ordering similar to MRI)
8383
stat = {
8484
count: count,
8585
time: time,
@@ -93,48 +93,41 @@ def self.stat(option = nil)
9393
committed: committed,
9494
init: init,
9595
max: max,
96-
peak_used: 0,
97-
peak_committed: 0,
98-
peak_init: 0,
99-
peak_max: 0,
100-
last_used: 0,
101-
last_committed: 0,
102-
last_init: 0,
103-
last_max: 0,
10496
}
105-
106-
memory_pool_names.each_with_index do |memory_pool_name, i|
107-
# Populate memory pool specific stats
108-
info = memory_pool_info[i]
109-
if info
110-
stat[memory_pool_name] = data = {
111-
used: info[0],
112-
committed: info[1],
113-
init: info[2],
114-
max: info[3],
115-
peak_used: info[4],
116-
peak_committed: info[5],
117-
peak_init: info[6],
118-
peak_max: info[7],
119-
last_used: info[8],
120-
last_committed: info[9],
121-
last_init: info[10],
122-
last_max: info[11],
123-
}
124-
125-
# Calculate stats across memory pools for peak_/last_ (we already know the values for current usage)
126-
data.each_pair do |key, value|
127-
stat[key] += value if key.start_with?('peak_', 'last_')
97+
stat.default = 0
98+
99+
unless Primitive.object_kind_of?(key, Symbol) # memory_pool_names are Strings
100+
memory_pool_names.each_with_index do |memory_pool_name, i|
101+
# Populate memory pool specific stats
102+
info = memory_pool_info[i]
103+
if info
104+
stat[memory_pool_name] = data = {
105+
used: info[0],
106+
committed: info[1],
107+
init: info[2],
108+
max: info[3],
109+
peak_used: info[4],
110+
peak_committed: info[5],
111+
peak_init: info[6],
112+
peak_max: info[7],
113+
last_used: info[8],
114+
last_committed: info[9],
115+
last_init: info[10],
116+
last_max: info[11],
117+
}
118+
119+
# Calculate stats across memory pools for peak_/last_ (we already know the values for current usage)
120+
data.each_pair do |k,v|
121+
stat[k] += v if k.start_with?('peak_', 'last_')
122+
end
128123
end
129124
end
130125
end
131126

132-
return stat unless option
133-
134-
if stat[option]
135-
stat[option]
127+
if key
128+
stat[key]
136129
else
137-
0
130+
stat
138131
end
139132
end
140133

0 commit comments

Comments
 (0)