on master help sign in
Merge pull request #1755 from mattias-lundell/master
6f032ccEdwin Brady
rts/idris_gc.c+7−7
@@ -69,7 +69,7 @@ void cheney(VM *vm) {
69 int i;
69 int i;
70 int ar;
70 int ar;
71 char* scan = vm->heap.heap;
71 char* scan = vm->heap.heap;
72−
72+
73 while(scan < vm->heap.next) {
73 while(scan < vm->heap.next) {
74 size_t inc = *((size_t*)scan);
74 size_t inc = *((size_t*)scan);
75 VAL heap_item = (VAL)(scan+sizeof(size_t));
75 VAL heap_item = (VAL)(scan+sizeof(size_t));
@@ -85,7 +85,7 @@ void cheney(VM *vm) {
85 }
85 }
86 break;
86 break;
87 case STROFFSET:
87 case STROFFSET:
88− heap_item->info.str_offset->str
88+ heap_item->info.str_offset->str
89 = copy(vm, heap_item->info.str_offset->str);
89 = copy(vm, heap_item->info.str_offset->str);
90 break;
90 break;
91 default: // Nothing to copy
91 default: // Nothing to copy
@@ -103,7 +103,7 @@ void idris_gc(VM* vm) {
103
103
104 char* newheap = malloc(vm->heap.size);
104 char* newheap = malloc(vm->heap.size);
105 char* oldheap = vm->heap.heap;
105 char* oldheap = vm->heap.heap;
106− if (vm->heap.old != NULL)
106+ if (vm->heap.old != NULL)
107 free(vm->heap.old);
107 free(vm->heap.old);
108
108
109 vm->heap.heap = newheap;
109 vm->heap.heap = newheap;
@@ -138,21 +138,21 @@ void idris_gc(VM* vm) {
138
138
139 if ((vm->heap.next - vm->heap.heap) > vm->heap.size >> 1) {
139 if ((vm->heap.next - vm->heap.heap) > vm->heap.size >> 1) {
140 vm->heap.size += vm->heap.growth;
140 vm->heap.size += vm->heap.growth;
141− }
141+ }
142 vm->heap.old = oldheap;
142 vm->heap.old = oldheap;
143−
143+
144 STATS_LEAVE_GC(vm->stats, vm->heap.size, vm->heap.next - vm->heap.heap)
144 STATS_LEAVE_GC(vm->stats, vm->heap.size, vm->heap.next - vm->heap.heap)
145 HEAP_CHECK(vm)
145 HEAP_CHECK(vm)
146}
146}
147
147
148void idris_gcInfo(VM* vm, int doGC) {
148void idris_gcInfo(VM* vm, int doGC) {
149− printf("Stack: <BOT %p> <TOP %p>\n", vm->valstack, vm->valstack_top);
149+ printf("Stack: <BOT %p> <TOP %p>\n", vm->valstack, vm->valstack_top);
150 printf("Final heap size %d\n", (int)(vm->heap.size));
150 printf("Final heap size %d\n", (int)(vm->heap.size));
151 printf("Final heap use %d\n", (int)(vm->heap.next - vm->heap.heap));
151 printf("Final heap use %d\n", (int)(vm->heap.next - vm->heap.heap));
152 if (doGC) { idris_gc(vm); }
152 if (doGC) { idris_gc(vm); }
153 printf("Final heap use after GC %d\n", (int)(vm->heap.next - vm->heap.heap));
153 printf("Final heap use after GC %d\n", (int)(vm->heap.next - vm->heap.heap));
154#ifdef IDRIS_ENABLE_STATS
154#ifdef IDRIS_ENABLE_STATS
155− printf("Total allocations %d\n", vm->stats.allocations);
155+ printf("Total allocations %" PRIu64 "\n", vm->stats.allocations);
156#endif
156#endif
157 printf("Number of collections %d\n", vm->stats.collections);
157 printf("Number of collections %d\n", vm->stats.collections);
158
158
rts/idris_stats.c+11−11
@@ -10,16 +10,16 @@ void print_stats(const Stats * stats) {
10 clock_t mut = total - stats->init_time - stats->gc_time - stats->exit_time;
10 clock_t mut = total - stats->init_time - stats->gc_time - stats->exit_time;
11 double mut_sec = (double)mut / CLOCKS_PER_SEC;
11 double mut_sec = (double)mut / CLOCKS_PER_SEC;
12
12
13− int avg_chunk = 0;
13+ uint64_t avg_chunk = 0;
14 if (stats->alloc_count > 0) {
14 if (stats->alloc_count > 0) {
15− avg_chunk = (int)((double)stats->allocations / (double)stats->alloc_count);
15+ avg_chunk = (uint64_t)((double)stats->allocations / (double)stats->alloc_count);
16 }
16 }
17
17
18− int alloc_rate = 0;
18+ uint64_t alloc_rate = 0;
19 if (mut > 0) {
19 if (mut > 0) {
20− alloc_rate = (int)((double)(stats->allocations) / mut_sec);
20+ alloc_rate = (uint64_t)((double)(stats->allocations) / mut_sec);
21 }
21 }
22−
22+
23 double gc_percent = 0.0;
23 double gc_percent = 0.0;
24 double productivity = 0.0;
24 double productivity = 0.0;
25 if (total > 0) {
25 if (total > 0) {
@@ -29,11 +29,11 @@ void print_stats(const Stats * stats) {
29
29
30 setlocale(LC_NUMERIC, "");
30 setlocale(LC_NUMERIC, "");
31 printf("\n");
31 printf("\n");
32− printf("%'20d bytes allocated in the heap\n", stats->allocations);
32+ printf("%'20" PRIu64 " bytes allocated in the heap\n", stats->allocations);
33− printf("%'20d bytes copied during GC\n", stats->copied);
33+ printf("%'20" PRIu64 " bytes copied during GC\n", stats->copied);
34− printf("%'20d maximum heap size\n", stats->max_heap_size);
34+ printf("%'20" PRIu32 " maximum heap size\n", stats->max_heap_size);
35− printf("%'20d chunks allocated in the heap\n", stats->alloc_count);
35+ printf("%'20" PRIu32 " chunks allocated in the heap\n", stats->alloc_count);
36− printf("%'20d average chunk size\n\n", avg_chunk);
36+ printf("%'20" PRIu64 " average chunk size\n\n", avg_chunk);
37
37
38 printf("GC called %d times\n\n", stats->collections);
38 printf("GC called %d times\n\n", stats->collections);
39
39
@@ -45,7 +45,7 @@ void print_stats(const Stats * stats) {
45
45
46 printf("%%GC time: %.2f%%\n\n", gc_percent);
46 printf("%%GC time: %.2f%%\n\n", gc_percent);
47
47
48− printf("Alloc rate %'d bytes per MUT sec\n\n", alloc_rate);
48+ printf("Alloc rate %'" PRIu64 " bytes per MUT sec\n\n", alloc_rate);
49
49
50 printf("Productivity %.2f%%\n", productivity);
50 printf("Productivity %.2f%%\n", productivity);
51}
51}
rts/idris_stats.h+10−8
@@ -3,16 +3,18 @@
3
3
4#ifdef IDRIS_ENABLE_STATS
4#ifdef IDRIS_ENABLE_STATS
5#include <time.h>
5#include <time.h>
6+#include <inttypes.h>
7+#include <stdint.h>
6#endif
8#endif
7
9
8
10
9// TODO: measure user time, exclusive/inclusive stats
11// TODO: measure user time, exclusive/inclusive stats
10typedef struct {
12typedef struct {
11#ifdef IDRIS_ENABLE_STATS
13#ifdef IDRIS_ENABLE_STATS
12− int allocations; // Size of allocated space in bytes for all execution time.
14+ uint64_t allocations; // Size of allocated space in bytes for all execution time.
13− int alloc_count; // How many times alloc is called.
15+ uint32_t alloc_count; // How many times alloc is called.
14− int copied; // Size of space copied during GC.
16+ uint64_t copied; // Size of space copied during GC.
15− int max_heap_size; // Maximum heap size achieved.
17+ uint32_t max_heap_size; // Maximum heap size achieved.
16
18
17 clock_t init_time; // Time spent for vm initialization.
19 clock_t init_time; // Time spent for vm initialization.
18 clock_t exit_time; // Time spent for vm termination.
20 clock_t exit_time; // Time spent for vm termination.
@@ -20,7 +22,7 @@ typedef struct {
20 clock_t max_gc_pause; // Time spent for longest gc.
22 clock_t max_gc_pause; // Time spent for longest gc.
21 clock_t start_time; // Time of rts entry point.
23 clock_t start_time; // Time of rts entry point.
22#endif // IDRIS_ENABLE_STATS
24#endif // IDRIS_ENABLE_STATS
23− int collections; // How many times gc called.
25+ uint32_t collections; // How many times gc called.
24} Stats; // without start time it's a monoid, can we remove start_time it somehow?
26} Stats; // without start time it's a monoid, can we remove start_time it somehow?
25
27
26void print_stats(const Stats * stats);
28void print_stats(const Stats * stats);
@@ -35,7 +37,7 @@ void aggregate_stats(Stats * stats1, const Stats * stats2);
35
37
36#define STATS_INIT_STATS(stats) \
38#define STATS_INIT_STATS(stats) \
37 memset(&stats, 0, sizeof(Stats)); \
39 memset(&stats, 0, sizeof(Stats)); \
38− stats.start_time = clock();
40+ stats.start_time = clock();
39
41
40#define STATS_ALLOC(stats, size) \
42#define STATS_ALLOC(stats, size) \
41 stats.allocations += size; \
43 stats.allocations += size; \
@@ -60,8 +62,8 @@ void aggregate_stats(Stats * stats1, const Stats * stats2);
60
62
61#else
63#else
62#define STATS_INIT_STATS(stats) memset(&stats, 0, sizeof(Stats));
64#define STATS_INIT_STATS(stats) memset(&stats, 0, sizeof(Stats));
63−#define STATS_ENTER_INIT(stats)
65+#define STATS_ENTER_INIT(stats)
64−#define STATS_LEAVE_INIT(stats)
66+#define STATS_LEAVE_INIT(stats)
65#define STATS_ENTER_EXIT(stats)
67#define STATS_ENTER_EXIT(stats)
66#define STATS_LEAVE_EXIT(stats)
68#define STATS_LEAVE_EXIT(stats)
67#define STATS_ALLOC(stats, size)
69#define STATS_ALLOC(stats, size)
test/runtest.pl+17−1
@@ -2,17 +2,32 @@
2
2
3use strict;
3use strict;
4use Cwd;
4use Cwd;
5+use Cwd 'abs_path';
6+use Env;
5
7
6my $exitstatus = 0;
8my $exitstatus = 0;
7my @idrOpts = ();
9my @idrOpts = ();
8
10
11+sub sandbox_path {
12+ my ($test_dir,) = @_;
13+ my $sandbox = abs_path("$test_dir/../../.cabal-sandbox/bin");
14+
15+ if ( -d $sandbox ) {
16+ return "PATH=$sandbox:$PATH";
17+ } else {
18+ return "";
19+ }
20+}
21+
9sub runtest {
22sub runtest {
10 my ($test, $update) = @_;
23 my ($test, $update) = @_;
11
24
25+ my $sandbox = sandbox_path($test);
26+
12 chdir($test);
27 chdir($test);
13
28
14 print "Running $test...\n";
29 print "Running $test...\n";
15− my $got = `./run @idrOpts`;
30+ my $got = `$sandbox ./run @idrOpts`;
16 my $exp = `cat expected`;
31 my $exp = `cat expected`;
17
32
18 open my $out, '>', 'output';
33 open my $out, '>', 'output';
@@ -62,6 +77,7 @@ if ($#ARGV>=0) {
62 }
77 }
63 }
78 }
64 @tests = sort @tests;
79 @tests = sort @tests;
80+
65 } elsif ($test eq "without") {
81 } elsif ($test eq "without") {
66 @args = @ARGV;
82 @args = @ARGV;
67 foreach my $file (@args) {
83 foreach my $file (@args) {