mwrap 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +1 -0
- data/.gitignore +3 -0
- data/.olddoc.yml +3 -1
- data/README +7 -5
- data/Rakefile +29 -1
- data/bin/mwrap +1 -1
- data/ext/mwrap/extconf.rb +8 -1
- data/ext/mwrap/mwrap.c +45 -23
- data/lib/mwrap_rack.rb +3 -5
- data/mwrap.gemspec +2 -2
- data/test/test_mwrap.rb +19 -12
- metadata +4 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 406933abeb7d63d1304c63f0f5aa7a2f4deb9ecb1820816886df8bfcf2d01601
|
4
|
+
data.tar.gz: 214975358778869db55691d8ddcac9e078cc16be6870e143094bb837d88551eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0a353c1ed720192b6dc63699d7d53661fc80c204429df3c93d4795b39cdec1d0e1b83c90e4250ddee11abd1911d578dd4f83516368a787a21fb1327de0ac32b
|
7
|
+
data.tar.gz: 28fd47f870ec74cd4c15570e6f6df0b9ee80ff30eb460185f841d2bc796836dd8aa6d82a7e3304bf811d22acc2dfb3e00fa4f92143a0cbb04dbd78e99ae7231e
|
data/.document
CHANGED
data/.gitignore
CHANGED
data/.olddoc.yml
CHANGED
@@ -5,4 +5,6 @@ rdoc_url: https://80x24.org/mwrap/
|
|
5
5
|
ml_url: https://80x24.org/mwrap-public/
|
6
6
|
public_email: mwrap-public@80x24.org
|
7
7
|
nntp_url:
|
8
|
-
|
8
|
+
- nntps://news.public-inbox.org/inbox.comp.lang.ruby.mwrap
|
9
|
+
imap_url:
|
10
|
+
- imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0
|
data/README
CHANGED
@@ -67,16 +67,18 @@ first two columns to find the hottest malloc locations.
|
|
67
67
|
mwrap 2.0.0+ also supports a Rack application endpoint,
|
68
68
|
it is documented at:
|
69
69
|
|
70
|
-
|
70
|
+
https://80x24.org/mwrap/MwrapRack.html
|
71
71
|
|
72
72
|
== Known problems
|
73
73
|
|
74
74
|
* 32-bit machines are prone to overflow (WONTFIX)
|
75
75
|
|
76
|
-
==
|
76
|
+
== Public mail archives and contact info:
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
* https://80x24.org/mwrap-public/
|
79
|
+
* nntps://80x24.org/inbox.comp.lang.ruby.mwrap
|
80
|
+
* imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0
|
81
|
+
* https://80x24.org/mwrap-public/_/text/help/#pop3
|
80
82
|
|
81
83
|
No subscription will ever be required to post, but HTML mail
|
82
84
|
will be rejected:
|
@@ -88,7 +90,7 @@ will be rejected:
|
|
88
90
|
git clone https://80x24.org/mwrap.git
|
89
91
|
|
90
92
|
Send all patches and pull requests (use "git request-pull" to format) to
|
91
|
-
|
93
|
+
mwrap-public@80x24.org. We do not use centralized or proprietary messaging
|
92
94
|
systems.
|
93
95
|
|
94
96
|
== License
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
2
2
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
3
3
|
require 'rake/testtask'
|
4
4
|
begin
|
@@ -14,3 +14,31 @@ task :default => :compile
|
|
14
14
|
|
15
15
|
c_files = File.readlines('MANIFEST').grep(%r{ext/.*\.[ch]$}).map!(&:chomp!)
|
16
16
|
task 'compile:mwrap' => c_files
|
17
|
+
|
18
|
+
olddoc = ENV['OLDDOC'] || 'olddoc'
|
19
|
+
rdoc = ENV['RDOC'] || 'rdoc'
|
20
|
+
task :rsync_docs do
|
21
|
+
require 'fileutils'
|
22
|
+
top = %w(README COPYING LATEST NEWS NEWS.atom.xml)
|
23
|
+
system("git", "set-file-times")
|
24
|
+
dest = ENV["RSYNC_DEST"] || "80x24.org:/srv/80x24/mwrap/"
|
25
|
+
FileUtils.rm_rf('doc')
|
26
|
+
sh "#{olddoc} prepare"
|
27
|
+
sh "#{rdoc} -f dark216" # dark216 requires olddoc 1.7+
|
28
|
+
File.unlink('doc/created.rid') rescue nil
|
29
|
+
File.unlink('doc/index.html') rescue nil
|
30
|
+
FileUtils.cp(top, 'doc')
|
31
|
+
sh "#{olddoc} merge"
|
32
|
+
|
33
|
+
Dir['doc/**/*'].each do |txt|
|
34
|
+
st = File.stat(txt)
|
35
|
+
if st.file?
|
36
|
+
gz = "#{txt}.gz"
|
37
|
+
tmp = "#{gz}.#$$"
|
38
|
+
sh("gzip --rsyncable -9 <#{txt} >#{tmp}")
|
39
|
+
File.utime(st.atime, st.mtime, tmp) # make nginx gzip_static happy
|
40
|
+
File.rename(tmp, gz)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
sh("rsync --chmod=Fugo=r #{ENV['RSYNC_OPT']} -av doc/ #{dest}/")
|
44
|
+
end
|
data/bin/mwrap
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
-
# Copyright (C)
|
3
|
+
# Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
4
4
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
5
5
|
require 'mwrap'
|
6
6
|
mwrap_so = $".grep(%r{/mwrap\.so\z})[0] or abort "mwrap.so not loaded"
|
data/ext/mwrap/extconf.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# Copyright (C)
|
2
|
+
# Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
3
3
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
4
4
|
require 'mkmf'
|
5
5
|
|
@@ -25,4 +25,11 @@ else
|
|
25
25
|
abort 'missing __builtin_add_overflow'
|
26
26
|
end
|
27
27
|
|
28
|
+
begin
|
29
|
+
if n = GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE]
|
30
|
+
$defs << "-DHEAP_PAGE_SIZE=#{n}"
|
31
|
+
end
|
32
|
+
rescue NameError
|
33
|
+
end
|
34
|
+
|
28
35
|
create_makefile 'mwrap'
|
data/ext/mwrap/mwrap.c
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C)
|
2
|
+
* Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
3
3
|
* License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
4
4
|
*/
|
5
5
|
#define _LGPL_SOURCE /* allows URCU to inline some stuff */
|
6
|
-
#include <ruby
|
6
|
+
#include <ruby.h> /* defines HAVE_RUBY_RACTOR_H on 3.0+ */
|
7
7
|
#include <ruby/thread.h>
|
8
8
|
#include <ruby/io.h>
|
9
9
|
#include <execinfo.h>
|
@@ -22,10 +22,24 @@
|
|
22
22
|
#include <urcu/rculist.h>
|
23
23
|
#include "jhash.h"
|
24
24
|
|
25
|
+
#if __STDC_VERSION__ >= 201112
|
26
|
+
# define MWRAP_TSD _Thread_local
|
27
|
+
#elif defined(__GNUC__)
|
28
|
+
# define MWRAP_TSD __thread
|
29
|
+
#else
|
30
|
+
# error _Thread_local nor __thread supported
|
31
|
+
#endif
|
32
|
+
|
25
33
|
static ID id_uminus;
|
26
34
|
const char *rb_source_location_cstr(int *line); /* requires 2.6.0dev */
|
27
35
|
extern int __attribute__((weak)) ruby_thread_has_gvl_p(void);
|
36
|
+
|
37
|
+
#ifdef HAVE_RUBY_RACTOR_H /* Ruby 3.0+ */
|
38
|
+
extern MWRAP_TSD void * __attribute__((weak)) ruby_current_ec;
|
39
|
+
#else /* Ruby 2.6-2.7 */
|
28
40
|
extern void * __attribute__((weak)) ruby_current_execution_context_ptr;
|
41
|
+
# define ruby_current_ec ruby_current_execution_context_ptr
|
42
|
+
#endif
|
29
43
|
extern void * __attribute__((weak)) ruby_current_vm_ptr; /* for rb_gc_count */
|
30
44
|
extern size_t __attribute__((weak)) rb_gc_count(void);
|
31
45
|
extern VALUE __attribute__((weak)) rb_cObject;
|
@@ -40,9 +54,12 @@ static size_t total_bytes_inc, total_bytes_dec;
|
|
40
54
|
/* match values in Ruby gc.c */
|
41
55
|
#define HEAP_PAGE_ALIGN_LOG 14
|
42
56
|
enum {
|
43
|
-
HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG)
|
57
|
+
HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG)
|
58
|
+
#ifndef HEAP_PAGE_SIZE /* Ruby 2.6-2.7 only */
|
59
|
+
,
|
44
60
|
REQUIRED_SIZE_BY_MALLOC = (sizeof(size_t) * 5),
|
45
61
|
HEAP_PAGE_SIZE = (HEAP_PAGE_ALIGN - REQUIRED_SIZE_BY_MALLOC)
|
62
|
+
#endif
|
46
63
|
};
|
47
64
|
|
48
65
|
#define IS_HEAP_PAGE_BODY ((struct src_loc *)-1)
|
@@ -75,7 +92,7 @@ static int resolving_malloc;
|
|
75
92
|
} \
|
76
93
|
} while (0)
|
77
94
|
|
78
|
-
static
|
95
|
+
static MWRAP_TSD size_t locating;
|
79
96
|
static size_t generation;
|
80
97
|
static size_t page_size;
|
81
98
|
static struct cds_lfht *totals;
|
@@ -139,8 +156,8 @@ __attribute__((constructor)) static void resolve_malloc(void)
|
|
139
156
|
_exit(1);
|
140
157
|
}
|
141
158
|
#endif /* !FreeBSD */
|
142
|
-
totals
|
143
|
-
if (!totals)
|
159
|
+
CMM_STORE_SHARED(totals, lfht_new());
|
160
|
+
if (!CMM_LOAD_SHARED(totals))
|
144
161
|
fprintf(stderr, "failed to allocate totals table\n");
|
145
162
|
|
146
163
|
err = pthread_atfork(call_rcu_before_fork,
|
@@ -152,11 +169,18 @@ __attribute__((constructor)) static void resolve_malloc(void)
|
|
152
169
|
--locating;
|
153
170
|
}
|
154
171
|
|
172
|
+
#ifdef NDEBUG
|
173
|
+
#define QUIET_CC_WARNING(var) (void)var;
|
174
|
+
#else
|
175
|
+
#define QUIET_CC_WARNING(var)
|
176
|
+
#endif
|
177
|
+
|
155
178
|
static void
|
156
179
|
mutex_lock(pthread_mutex_t *m)
|
157
180
|
{
|
158
181
|
int err = pthread_mutex_lock(m);
|
159
182
|
assert(err == 0);
|
183
|
+
QUIET_CC_WARNING(err)
|
160
184
|
}
|
161
185
|
|
162
186
|
static void
|
@@ -164,6 +188,7 @@ mutex_unlock(pthread_mutex_t *m)
|
|
164
188
|
{
|
165
189
|
int err = pthread_mutex_unlock(m);
|
166
190
|
assert(err == 0);
|
191
|
+
QUIET_CC_WARNING(err)
|
167
192
|
}
|
168
193
|
|
169
194
|
#ifndef HAVE_MEMPCPY
|
@@ -214,7 +239,7 @@ static char *int2str(int num, char *dst, size_t * size)
|
|
214
239
|
static int has_ec_p(void)
|
215
240
|
{
|
216
241
|
return (ruby_thread_has_gvl_p() && ruby_current_vm_ptr &&
|
217
|
-
|
242
|
+
ruby_current_ec);
|
218
243
|
}
|
219
244
|
|
220
245
|
struct acc {
|
@@ -367,7 +392,7 @@ acc_stddev(const struct acc *acc)
|
|
367
392
|
return DBL2NUM(acc_stddev_dbl(acc));
|
368
393
|
}
|
369
394
|
|
370
|
-
static struct src_loc *totals_add_rcu(struct src_loc *k)
|
395
|
+
static struct src_loc *totals_add_rcu(const struct src_loc *k)
|
371
396
|
{
|
372
397
|
struct cds_lfht_iter iter;
|
373
398
|
struct cds_lfht_node *cur;
|
@@ -375,7 +400,7 @@ static struct src_loc *totals_add_rcu(struct src_loc *k)
|
|
375
400
|
struct cds_lfht *t;
|
376
401
|
|
377
402
|
again:
|
378
|
-
t =
|
403
|
+
t = CMM_LOAD_SHARED(totals);
|
379
404
|
if (!t) goto out_unlock;
|
380
405
|
cds_lfht_lookup(t, k->hval, loc_eq, k, &iter);
|
381
406
|
cur = cds_lfht_iter_get_node(&iter);
|
@@ -417,7 +442,7 @@ static struct src_loc *update_stats_rcu_lock(size_t size, uintptr_t caller)
|
|
417
442
|
static const size_t xlen = sizeof(caller);
|
418
443
|
char *dst;
|
419
444
|
|
420
|
-
if (caa_unlikely(!totals)) return 0;
|
445
|
+
if (caa_unlikely(!CMM_LOAD_SHARED(totals))) return 0;
|
421
446
|
if (locating++) goto out; /* do not recurse into another *alloc */
|
422
447
|
|
423
448
|
uatomic_add(&total_bytes_inc, size);
|
@@ -632,9 +657,9 @@ internal_memalign(void **pp, size_t alignment, size_t size, uintptr_t caller)
|
|
632
657
|
p = ptr_align(p, alignment);
|
633
658
|
h = ptr2hdr(p);
|
634
659
|
alloc_insert_rcu(l, h, size, real);
|
635
|
-
update_stats_rcu_unlock(l);
|
636
660
|
*pp = p;
|
637
661
|
}
|
662
|
+
update_stats_rcu_unlock(l);
|
638
663
|
}
|
639
664
|
|
640
665
|
return real ? 0 : ENOMEM;
|
@@ -643,16 +668,14 @@ internal_memalign(void **pp, size_t alignment, size_t size, uintptr_t caller)
|
|
643
668
|
static void *
|
644
669
|
memalign_result(int err, void *p)
|
645
670
|
{
|
646
|
-
if (caa_unlikely(err))
|
671
|
+
if (caa_unlikely(err))
|
647
672
|
errno = err;
|
648
|
-
return 0;
|
649
|
-
}
|
650
673
|
return p;
|
651
674
|
}
|
652
675
|
|
653
676
|
void *memalign(size_t alignment, size_t size)
|
654
677
|
{
|
655
|
-
void *p;
|
678
|
+
void *p = NULL;
|
656
679
|
int err = internal_memalign(&p, alignment, size, RETURN_ADDRESS(0));
|
657
680
|
return memalign_result(err, p);
|
658
681
|
}
|
@@ -667,7 +690,7 @@ void cfree(void *) __attribute__((alias("free")));
|
|
667
690
|
|
668
691
|
void *valloc(size_t size)
|
669
692
|
{
|
670
|
-
void *p;
|
693
|
+
void *p = NULL;
|
671
694
|
int err = internal_memalign(&p, page_size, size, RETURN_ADDRESS(0));
|
672
695
|
return memalign_result(err, p);
|
673
696
|
}
|
@@ -685,7 +708,7 @@ void *valloc(size_t size)
|
|
685
708
|
void *pvalloc(size_t size)
|
686
709
|
{
|
687
710
|
size_t alignment = page_size;
|
688
|
-
void *p;
|
711
|
+
void *p = NULL;
|
689
712
|
int err;
|
690
713
|
|
691
714
|
if (add_overflow_p(size, alignment)) {
|
@@ -808,7 +831,7 @@ static void *dump_to_file(void *x)
|
|
808
831
|
|
809
832
|
++locating;
|
810
833
|
rcu_read_lock();
|
811
|
-
t =
|
834
|
+
t = CMM_LOAD_SHARED(totals);
|
812
835
|
if (!t)
|
813
836
|
goto out_unlock;
|
814
837
|
cds_lfht_for_each_entry(t, &iter, l, hnode) {
|
@@ -877,7 +900,7 @@ static void *totals_reset(void *ign)
|
|
877
900
|
uatomic_set(&total_bytes_dec, 0);
|
878
901
|
|
879
902
|
rcu_read_lock();
|
880
|
-
t =
|
903
|
+
t = CMM_LOAD_SHARED(totals);
|
881
904
|
cds_lfht_for_each_entry(t, &iter, l, hnode) {
|
882
905
|
uatomic_set(&l->total, 0);
|
883
906
|
uatomic_set(&l->allocations, 0);
|
@@ -945,7 +968,7 @@ static VALUE dump_each_rcu(VALUE x)
|
|
945
968
|
struct cds_lfht_iter iter;
|
946
969
|
struct src_loc *l;
|
947
970
|
|
948
|
-
t =
|
971
|
+
t = CMM_LOAD_SHARED(totals);
|
949
972
|
cds_lfht_for_each_entry(t, &iter, l, hnode) {
|
950
973
|
VALUE v[6];
|
951
974
|
if (l->total <= a->min) continue;
|
@@ -1049,9 +1072,9 @@ static VALUE mwrap_aref(VALUE mod, VALUE loc)
|
|
1049
1072
|
|
1050
1073
|
if (!k) return val;
|
1051
1074
|
|
1075
|
+
t = CMM_LOAD_SHARED(totals);
|
1076
|
+
if (!t) return val;
|
1052
1077
|
rcu_read_lock();
|
1053
|
-
t = rcu_dereference(totals);
|
1054
|
-
if (!t) goto out_unlock;
|
1055
1078
|
|
1056
1079
|
cds_lfht_lookup(t, k->hval, loc_eq, k, &iter);
|
1057
1080
|
cur = cds_lfht_iter_get_node(&iter);
|
@@ -1059,7 +1082,6 @@ static VALUE mwrap_aref(VALUE mod, VALUE loc)
|
|
1059
1082
|
l = caa_container_of(cur, struct src_loc, hnode);
|
1060
1083
|
val = TypedData_Wrap_Struct(cSrcLoc, &src_loc_type, l);
|
1061
1084
|
}
|
1062
|
-
out_unlock:
|
1063
1085
|
rcu_read_unlock();
|
1064
1086
|
return val;
|
1065
1087
|
}
|
data/lib/mwrap_rack.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) all contributors <mwrap-public@80x24.org>
|
2
2
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
3
3
|
# frozen_string_literal: true
|
4
4
|
require 'mwrap'
|
@@ -17,9 +17,6 @@ require 'cgi'
|
|
17
17
|
# map('/MWRAP') { run(MwrapRack.new) }
|
18
18
|
# map('/') { run(your_normal_app) }
|
19
19
|
#
|
20
|
-
# A live demo is available at https://80x24.org/MWRAP/
|
21
|
-
# (warning the demo machine is 32-bit, so counters will overflow)
|
22
|
-
#
|
23
20
|
# This module is only available in mwrap 2.0.0+
|
24
21
|
class MwrapRack
|
25
22
|
module HtmlResponse # :nodoc:
|
@@ -115,10 +112,11 @@ class MwrapRack
|
|
115
112
|
end
|
116
113
|
|
117
114
|
GC_STAT_URL = 'https://docs.ruby-lang.org/en/trunk/GC.html#method-c-stat'
|
118
|
-
GC_STAT_HELP = <<~
|
115
|
+
GC_STAT_HELP = <<~EOM
|
119
116
|
<p>Non-Infinity lifespans can indicate fragmentation.
|
120
117
|
<p>See <a
|
121
118
|
href="#{GC_STAT_URL}">#{GC_STAT_URL}</a> for info on GC.stat values.
|
119
|
+
EOM
|
122
120
|
|
123
121
|
def each
|
124
122
|
Mwrap.quiet do
|
data/mwrap.gemspec
CHANGED
@@ -12,9 +12,9 @@ desc = `git describe --abbrev=4 HEAD`.strip.tr('-', '.').delete_prefix('v')
|
|
12
12
|
|
13
13
|
Gem::Specification.new do |s|
|
14
14
|
s.name = 'mwrap'
|
15
|
-
s.version = desc.empty? ? '2.
|
15
|
+
s.version = desc.empty? ? '2.2.0' : desc
|
16
16
|
s.homepage = 'https://80x24.org/mwrap/'
|
17
|
-
s.authors = ["
|
17
|
+
s.authors = ["mwrap hackers"]
|
18
18
|
s.summary = 'LD_PRELOAD malloc wrapper for Ruby'
|
19
19
|
s.executables = %w(mwrap)
|
20
20
|
s.files = manifest
|
data/test/test_mwrap.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# Copyright (C)
|
2
|
+
# Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
3
3
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
4
4
|
require 'test/unit'
|
5
5
|
require 'mwrap'
|
@@ -29,7 +29,8 @@ class TestMwrap < Test::Unit::TestCase
|
|
29
29
|
tmp.rewind
|
30
30
|
lines = tmp.readlines
|
31
31
|
line_1 = lines.grep(/\s-e:1\b/)[0].strip
|
32
|
-
|
32
|
+
bytes = line_1.split(/\s+/)[0].to_i
|
33
|
+
assert_operator bytes, :>=, 10001
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -42,7 +43,7 @@ class TestMwrap < Test::Unit::TestCase
|
|
42
43
|
res = system(env, *cmd, { 5 => tmp })
|
43
44
|
assert res, $?.inspect
|
44
45
|
tmp.rewind
|
45
|
-
assert_match(/\
|
46
|
+
assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
|
46
47
|
|
47
48
|
env['MWRAP'] = 'dump_fd:1,dump_min:10000'
|
48
49
|
tmp.rewind
|
@@ -50,14 +51,14 @@ class TestMwrap < Test::Unit::TestCase
|
|
50
51
|
res = system(env, *cmd, { 1 => tmp })
|
51
52
|
assert res, $?.inspect
|
52
53
|
tmp.rewind
|
53
|
-
assert_match(/\
|
54
|
+
assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
|
54
55
|
|
55
56
|
tmp.rewind
|
56
57
|
tmp.truncate(0)
|
57
58
|
env['MWRAP'] = "dump_path:#{tmp.path},dump_min:10000"
|
58
59
|
res = system(env, *cmd)
|
59
60
|
assert res, $?.inspect
|
60
|
-
assert_match(/\
|
61
|
+
assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
|
61
62
|
|
62
63
|
tmp.rewind
|
63
64
|
tmp.truncate(0)
|
@@ -98,7 +99,7 @@ class TestMwrap < Test::Unit::TestCase
|
|
98
99
|
tmp.rewind
|
99
100
|
buf = tmp.read
|
100
101
|
assert_not_match(/\s+-e:1$/, buf)
|
101
|
-
assert_match(/\
|
102
|
+
assert_match(/\b2\d{4}\s+[0-9]\d*\s+-e:3$/, buf)
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
@@ -176,8 +177,8 @@ class TestMwrap < Test::Unit::TestCase
|
|
176
177
|
-e GC.disable
|
177
178
|
-e keep=("0"*10000)
|
178
179
|
-e loc=Mwrap["-e:3"]
|
179
|
-
-e
|
180
|
-
)
|
180
|
+
-e
|
181
|
+
) + [ 'loc.each{|size,gen|p([size,gen,count]) if size > 10000}' ]
|
181
182
|
buf = IO.popen(@@env, cmd, &:read)
|
182
183
|
assert_predicate $?, :success?
|
183
184
|
assert_match(/\A\[\s*\d+,\s*\d+,\s*\d+\]\s*\z/s, buf)
|
@@ -230,7 +231,8 @@ class TestMwrap < Test::Unit::TestCase
|
|
230
231
|
loc.name == k or abort 'SourceLocation#name broken'
|
231
232
|
loc.total >= 10000 or abort 'SourceLocation#total broken'
|
232
233
|
loc.frees == 0 or abort 'SourceLocation#frees broken'
|
233
|
-
loc.allocations
|
234
|
+
loc.allocations >= 1 or
|
235
|
+
abort "SourceLocation#allocations broken: #{loc.allocations}"
|
234
236
|
seen = false
|
235
237
|
loc.each do |*x| seen = x end
|
236
238
|
seen[1] == loc.total or 'SourceLocation#each broken'
|
@@ -240,7 +242,9 @@ class TestMwrap < Test::Unit::TestCase
|
|
240
242
|
freed = false
|
241
243
|
until freed
|
242
244
|
freed = true
|
243
|
-
loc.each do
|
245
|
+
loc.each do |size, gen|
|
246
|
+
freed = false if size >= 10000
|
247
|
+
end
|
244
248
|
end
|
245
249
|
loc.frees == 1 or abort 'SourceLocation#frees broken (after free)'
|
246
250
|
Float === loc.mean_lifespan or abort 'mean_lifespan broken'
|
@@ -264,8 +268,9 @@ class TestMwrap < Test::Unit::TestCase
|
|
264
268
|
assert_separately(+"#{<<~"begin;"}\n#{<<~'end;'}")
|
265
269
|
begin;
|
266
270
|
require 'mwrap'
|
267
|
-
before =
|
271
|
+
before = nil
|
268
272
|
res = Mwrap.quiet do |depth|
|
273
|
+
before = __LINE__
|
269
274
|
depth == 1 or abort 'depth is not 1'
|
270
275
|
('a' * 10000).clear
|
271
276
|
Mwrap.quiet { |d| d == 2 or abort 'depth is not 2' }
|
@@ -304,7 +309,9 @@ class TestMwrap < Test::Unit::TestCase
|
|
304
309
|
gen <= GC.count && gen >= 0 or abort "bad generation: #{gen}"
|
305
310
|
(0 == (addr & 16383)) or abort "addr not aligned: #{'%x' % addr}"
|
306
311
|
end
|
307
|
-
|
312
|
+
if RUBY_VERSION.to_f < 3.1 # 3.1+ uses mmap on platforms we care about
|
313
|
+
nr == ap or abort "HeapPageBody.each missed page #{nr} != #{ap}"
|
314
|
+
end
|
308
315
|
10.times { (1..20000).to_a.map(&:to_s) }
|
309
316
|
3.times { GC.start }
|
310
317
|
Mwrap::HeapPageBody.stat(h)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mwrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- mwrap hackers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|
@@ -81,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
requirements: []
|
84
|
-
|
85
|
-
rubygems_version: 2.7.7
|
84
|
+
rubygems_version: 3.0.2
|
86
85
|
signing_key:
|
87
86
|
specification_version: 4
|
88
87
|
summary: LD_PRELOAD malloc wrapper for Ruby
|