Callref expressions support for Global Compiler
[nit.git] / src / compiler / memory_logger.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Extension to inject memory-tracing instrumentation in code generated by `nitc`.
16 module memory_logger
17
18 import abstract_compiler
19
20 redef class ToolContext
21 # --trace-memory
22 var opt_trace_memory = new OptionBool("Enable dynamic measure of memory usage", "--trace-memory")
23
24 init do
25 self.option_context.add_option opt_trace_memory
26 end
27 end
28
29 redef class AbstractCompiler
30 redef fun compile_before_main(v)
31 do
32 super
33
34 if not modelbuilder.toolcontext.opt_trace_memory.value then return
35
36 header.add_decl("#include <time.h>")
37 header.add_decl("extern FILE *mlog;")
38 header.add_decl("extern struct timespec mlog_last;")
39 header.add_decl("extern struct timespec mlog_time0;")
40 v.add_decl("FILE *mlog;")
41 v.add_decl("struct timespec mlog_last;")
42 v.add_decl("struct timespec mlog_time0;")
43 end
44
45 redef fun compile_begin_main(v)
46 do
47 super
48
49 if not modelbuilder.toolcontext.opt_trace_memory.value then return
50
51 v.add("mlog = fopen(\"memory.log\", \"w\");")
52 v.add("clock_gettime(CLOCK_MONOTONIC, &mlog_time0);")
53 end
54 end
55
56 redef class AbstractCompilerVisitor
57 redef fun nit_alloc(size, tag)
58 do
59 if not compiler.modelbuilder.toolcontext.opt_trace_memory.value then return super
60
61 # Log time each 10ms (ie 1e7ns)
62 var tw = get_name("mtw")
63 add_decl("struct timespec {tw};")
64 add("clock_gettime(CLOCK_MONOTONIC, &{tw});")
65 add("if(mlog_last.tv_sec < {tw}.tv_sec || mlog_last.tv_nsec + 1e7 < {tw}.tv_nsec) \{")
66 add("mlog_last = {tw};")
67 add("fprintf(mlog, \"# %f\\n\", 1000.0*{tw}.tv_sec + 1e-6*{tw}.tv_nsec - (1000.0*mlog_time0.tv_sec + 1e-6*mlog_time0.tv_nsec));")
68 add("\}")
69
70 # Print size and tag the mlog
71 var str = "\"+\\t%d\\t%s\\n\", {size}, \"{tag or else "?"}\""
72 add("fprintf(mlog, {str});")
73
74 return super
75 end
76 end