mwrap 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|