]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add support for [Profile] method attribute 8b5d74dceffec42c90ba74a457e2d1cb2e1c7fcd
authorJürg Billeter <j@bitron.ch>
Fri, 20 Apr 2012 12:05:15 +0000 (14:05 +0200)
committerJürg Billeter <j@bitron.ch>
Fri, 20 Apr 2012 12:06:48 +0000 (14:06 +0200)
This allows simple method-level profiling. Requires GCC.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodmodule.vala

index 866e8b9e278c90a3fe4014e8c586b81a33810081..6a1b890b3b888c2220ac0df7e0e440a5fc8b7a93 100644 (file)
@@ -3488,6 +3488,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
                }
 
+               if (current_method != null && current_method.get_attribute ("Profile") != null) {
+                       string prefix = "_vala_prof_%s".printf (get_ccode_real_name (current_method));
+
+                       var timer = new CCodeIdentifier (prefix + "_timer");
+
+                       var stop_call = new CCodeFunctionCall (new CCodeIdentifier ("g_timer_stop"));
+                       stop_call.add_argument (timer);
+                       ccode.add_expression (stop_call);
+               }
+
                if (is_in_constructor ()) {
                        ccode.add_return (new CCodeIdentifier ("obj"));
                } else if (is_in_destructor ()) {
index be69a1c32c13151d7b59b7b81f7d2b63926c6167..b03f88986be55a8c601c0c783dc830674527face 100644 (file)
@@ -258,6 +258,8 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
 
                check_type (m.return_type);
 
+               bool profile = m.get_attribute ("Profile") != null;
+
                if (m.get_attribute ("NoArrayLength") != null) {
                        Report.deprecated (m.source_reference, "NoArrayLength attribute is deprecated, use [CCode (array_length = false)] instead.");
                }
@@ -300,6 +302,60 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                        }
                }
 
+               if (profile) {
+                       string prefix = "_vala_prof_%s".printf (get_ccode_real_name (m));
+
+                       cfile.add_include ("stdio.h");
+
+                       var counter = new CCodeIdentifier (prefix + "_counter");
+                       var counter_decl = new CCodeDeclaration ("gint");
+                       counter_decl.add_declarator (new CCodeVariableDeclarator (counter.name));
+                       counter_decl.modifiers = CCodeModifiers.STATIC;
+                       cfile.add_type_member_declaration (counter_decl);
+
+                       var timer = new CCodeIdentifier (prefix + "_timer");
+                       var timer_decl = new CCodeDeclaration ("GTimer *");
+                       timer_decl.add_declarator (new CCodeVariableDeclarator (timer.name));
+                       timer_decl.modifiers = CCodeModifiers.STATIC;
+                       cfile.add_type_member_declaration (timer_decl);
+
+                       var constructor = new CCodeFunction (prefix + "_init");
+                       constructor.modifiers = CCodeModifiers.STATIC;
+                       constructor.attributes = "__attribute__((constructor))";
+                       cfile.add_function_declaration (constructor);
+                       push_function (constructor);
+
+                       ccode.add_assignment (timer, new CCodeFunctionCall (new CCodeIdentifier ("g_timer_new")));
+
+                       var stop_call = new CCodeFunctionCall (new CCodeIdentifier ("g_timer_stop"));
+                       stop_call.add_argument (timer);
+                       ccode.add_expression (stop_call);
+
+                       pop_function ();
+                       cfile.add_function (constructor);
+
+
+                       var destructor = new CCodeFunction (prefix + "_exit");
+                       destructor.modifiers = CCodeModifiers.STATIC;
+                       destructor.attributes = "__attribute__((destructor))";
+                       cfile.add_function_declaration (destructor);
+                       push_function (destructor);
+
+                       var elapsed_call = new CCodeFunctionCall (new CCodeIdentifier ("g_timer_elapsed"));
+                       elapsed_call.add_argument (timer);
+                       elapsed_call.add_argument (new CCodeConstant ("NULL"));
+
+                       var print_call = new CCodeFunctionCall (new CCodeIdentifier ("fprintf"));
+                       print_call.add_argument (new CCodeIdentifier ("stderr"));
+                       print_call.add_argument (new CCodeConstant ("\"%s: %%gs (%%d calls)\\n\"".printf (m.get_full_name ())));
+                       print_call.add_argument (elapsed_call);
+                       print_call.add_argument (counter);
+                       ccode.add_expression (print_call);
+
+                       pop_function ();
+                       cfile.add_function (destructor);
+               }
+
                CCodeFunction function;
                function = new CCodeFunction (get_ccode_real_name (m));
 
@@ -560,10 +616,32 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                        }
                }
 
+               if (profile) {
+                       string prefix = "_vala_prof_%s".printf (get_ccode_real_name (m));
+
+                       var counter = new CCodeIdentifier (prefix + "_counter");
+                       ccode.add_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, counter));
+
+                       var timer = new CCodeIdentifier (prefix + "_timer");
+                       var cont_call = new CCodeFunctionCall (new CCodeIdentifier ("g_timer_continue"));
+                       cont_call.add_argument (timer);
+                       ccode.add_expression (cont_call);
+               }
+
                if (m.body != null) {
                        m.body.emit (this);
                }
 
+               if (profile) {
+                       string prefix = "_vala_prof_%s".printf (get_ccode_real_name (m));
+
+                       var timer = new CCodeIdentifier (prefix + "_timer");
+
+                       var stop_call = new CCodeFunctionCall (new CCodeIdentifier ("g_timer_stop"));
+                       stop_call.add_argument (timer);
+                       ccode.add_expression (stop_call);
+               }
+
                // generate *_real_* functions for virtual methods
                // also generate them for abstract methods of classes to prevent faulty subclassing
                if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) {