Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53373 - in sandbox/tools/profile_templates: . src test
From: steven_at_[hidden]
Date: 2009-05-28 19:26:32


Author: steven_watanabe
Date: 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
New Revision: 53373
URL: http://svn.boost.org/trac/boost/changeset/53373

Log:
Intermediate commit -- this is broken
Text files modified:
   sandbox/tools/profile_templates/preprocess.pl | 30 ++++++-
   sandbox/tools/profile_templates/src/filter.cpp | 21 ++--
   sandbox/tools/profile_templates/src/postprocess.cpp | 157 ++++++++++++++++++++++++++-------------
   sandbox/tools/profile_templates/template_profiler.hpp | 49 +++++++----
   sandbox/tools/profile_templates/test/test.cpp | 28 ++++++
   5 files changed, 196 insertions(+), 89 deletions(-)

Modified: sandbox/tools/profile_templates/preprocess.pl
==============================================================================
--- sandbox/tools/profile_templates/preprocess.pl (original)
+++ sandbox/tools/profile_templates/preprocess.pl 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
@@ -1,6 +1,6 @@
 # preprocess.pl
 #
-# Copyright (c) 2008
+# Copyright (c) 2008-2009
 # Steven Watanabe
 #
 # Distributed under the Boost Software License, Version 1.0. (See
@@ -16,7 +16,7 @@
 
 $backslashed_lines = qr/(?>(?>\\(?>\n|\r\n)|.)*)/;
 $string = qr/(?>\"(?>\\\\|\\\"|[^\"])*\"|'(?>\\\\|\\'|[^'])*')/;
-$comment = qr{(?>//$backslashed_lines|/\*(?>[^*]|\*(?!/))*\*/)}; #as far as we are concerned any text between off and on is a comment
+$comment = qr{(?>//$backslashed_lines|/\*(?>[^*]|\*(?!/))*\*/)};
 $pp = qr/(?>#$backslashed_lines)/;
 $ignored = qr/(?>$string|$comment|$pp)/;
 $parens = qr/(?>\((?>(?>(?>$ignored|[^()])+)|(??{$parens}))*\))/;
@@ -26,15 +26,35 @@
 
 $control = qr/(?:\b(?:__attribute__|__if_exists|__if_not_exists|for|while|if|catch|switch)\b)/;
 $modifiers = qr/(?:\b(?:try|const|volatile)\b)/;
-$start = qr/(?:^|\G|[{};])(?>$ws*)/;
+$start = qr/(?:^|\G|(?<=[{};]))(?>$ws*)/;
 $body = qr/(?:(?!$control)(?>$ignored|[^{};]))/;
 $end = qr/(?:$parens|\])/;
 $body_start = qr/(?>$ws*(?:$modifiers$ws*)*\{)/;
 
-$function_header = qr/(?>($start)($body*?$end)($body_start))/;
+$function_header = qr/(?>(?:$start)(?:$body*?$end)(?:$body_start))/;
+
+@braces = ();
+
+sub process {
+ my $header = $_[0];
+ my $open_brace = $_[1];
+ my $close_brace = $_[2];
+
+ if($header) {
+ push(@braces, " TEMPLATE_PROFILE_EXIT() }");
+ return("$header TEMPLATE_PROFILE_ENTER()");
+ } elsif($open_brace) {
+ push(@braces, "}");
+ return($open_brace);
+ } elsif($close_brace) {
+ return(pop(@braces));
+ } else {
+ die("This should only be called if the pattern matched: \$$_[0],$_[1],$_[2],$_[3],\$");
+ }
+}
 
 while(<>) {
- s/($ignored)|((?>$class_header|$function_header))/$1?$1:"$2 PROFILE_TRACER\(\); "/ge;
+ s/(($ignored)|((?>$class_header|$function_header))|([{])|([}]))/$2?$2:process($3,$4,$5)/ge;
     print "#include <template_profiler.hpp>\n";
     print;
 }

Modified: sandbox/tools/profile_templates/src/filter.cpp
==============================================================================
--- sandbox/tools/profile_templates/src/filter.cpp (original)
+++ sandbox/tools/profile_templates/src/filter.cpp 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
@@ -1,6 +1,6 @@
 // filter.cpp
 //
-// Copyright (c) 2008
+// Copyright (c) 2008-2009
 // Steven Watanabe
 //
 // Distributed under the Boost Software License, Version 1.0. (See
@@ -36,13 +36,14 @@
                 }
                 ++counter;
 #ifdef _MSC_VER
- int instantiations = counter / 2;
+ if(counter % 400 == 0) {
+ std::fprintf(stderr, "On Instantiation %d\n", counter/4);
+ }
 #else
- int instantiations = counter;
-#endif
- if(instantiations % 100 == 0) {
- std::fprintf(stderr, "On Instantiation %d\n", instantiations);
+ if(counter % 200 == 0) {
+ std::fprintf(stderr, "On Instantiation %d\n", counter/2);
                 }
+#endif
             }
             buffer.clear();
             matched = false;
@@ -59,7 +60,7 @@
 }
 
 void copy_call_graph() {
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && 0
     std::string buffer;
     int ch;
     int pos = 0;
@@ -72,8 +73,8 @@
                 for(std::size_t i = 0; i < buffer.size(); ++i) {
                     std::putchar(buffer[i]);
                 }
- if(++counter % 100 == 0) {
- std::fprintf(stderr, "On Instantiation %d\n", counter);
+ if(++counter % 200 == 0) {
+ std::fprintf(stderr, "On Instantiation %d\n", counter/2);
                 }
                 buffer.clear();
                 matched = false;
@@ -123,7 +124,7 @@
             pos = 0;
         }
     }
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || 1
     // trying to figure out what we should copy is too hard.
     int ch;
     while((ch = std::getchar()) != EOF) {

Modified: sandbox/tools/profile_templates/src/postprocess.cpp
==============================================================================
--- sandbox/tools/profile_templates/src/postprocess.cpp (original)
+++ sandbox/tools/profile_templates/src/postprocess.cpp 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
@@ -1,6 +1,6 @@
 // postprocess.cpp
 //
-// Copyright (c) 2008
+// Copyright (c) 2008-2009
 // Steven Watanabe
 //
 // Distributed under the Boost Software License, Version 1.0. (See
@@ -10,6 +10,7 @@
 #include <boost/regex.hpp>
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/numeric/conversion/cast.hpp>
 #include <string>
 #include <iostream>
 #include <fstream>
@@ -23,7 +24,10 @@
 
 #ifdef _MSC_VER
 
-boost::regex warning_message("(.*) : warning C4150: deletion of pointer to incomplete type 'template_profiler::incomplete'; no destructor called");
+#pragma warning(disable:4512)
+
+boost::regex enter_message("(.*) : warning C4150: deletion of pointer to incomplete type 'template_profiler::incomplete_enter'; no destructor called");
+boost::regex exit_message("(.*) : warning C4150: deletion of pointer to incomplete type 'template_profiler::incomplete_exit'; no destructor called");
 boost::regex call_graph_line(" (.*)\\((\\d+)\\) : see reference to .*");
 boost::regex split_file_and_line("(.*)\\((\\d+)\\)");
 
@@ -31,13 +35,15 @@
 
 #if (__GNUC__ < 4) || (__GNUC_MINOR__ < 3)
 
-boost::regex warning_message("(.*): warning: division by zero in .template_profiler::value / 0.");
+boost::regex enter_message("(.*): warning: division by zero in .template_profiler::enter_value / 0.");
+boost::regex exit_message("(.*): warning: division by zero in .template_profiler::exit_value / 0.");
 boost::regex call_graph_line("(.*):(\\d+): instantiated from .*");
 boost::regex split_file_and_line("(.*):(\\d+)");
 
 #else
 
-boost::regex warning_message("(.*): warning: .int template_profiler::f\\(int\\).*");
+boost::regex enter_message("(.*): warning: .int template_profiler::enter\\(int\\).*");
+boost::regex exit_message("(.*): warning: .int template_profiler::exit\\(int\\).*");
 boost::regex call_graph_line("(.*):(\\d+): instantiated from .*");
 boost::regex split_file_and_line("(.*):(\\d+)");
 
@@ -94,6 +100,62 @@
     return(os);
 }
 
+class instantiation_state {
+public:
+ instantiation_state(std::map<const line_id*, node_info>& g) : graph(g) {}
+ void finish_instantiation() {
+ std::cerr << "finish_instantiation, state.size(): " << state.size() << std::endl;
+ if(state.empty() || !state.back()) {
+ std::cerr << "attempt to finish unstarted instantiation: " << state.size() << std::endl;
+ std::exit(1);
+ }
+ state.pop_back();
+ pending_children.pop_back();
+ }
+ void add_instantiation(const line_id* new_line, std::size_t backtrace_size) {
+ if(backtrace_size == 0) {
+ std::cerr << "non-template" << std::endl;
+ // top level non-template
+ backtrace_size = state.size() + 1;
+ } else {
+ ++backtrace_size;
+ }
+ std::cerr << "backtrace size: " << backtrace_size << ", state.size(): " << state.size() << std::endl;
+ if(backtrace_size < state.size()) {
+ std::cerr << "Instantiation not exited." << std::endl;
+ std::exit(1);
+ }
+ ++graph[new_line].count;
+ std::cerr << "Adding lines" << std::endl;
+ BOOST_FOREACH(const line_id* line, state) {
+ if(line) {
+ add_child(line, new_line);
+ }
+ }
+ state.resize(backtrace_size);
+ pending_children.resize(backtrace_size);
+ state.back() = new_line;
+ BOOST_FOREACH(const line_id* child, pending_children.back()) {
+ add_child(new_line, child);
+ }
+ BOOST_FOREACH(std::vector<const line_id*>& v, pending_children) {
+ v.push_back(new_line);
+ }
+ }
+private:
+ void add_child(const line_id* parent, const line_id* child) {
+ std::cerr << "parent: " << parent << ", child: " << child << std::endl;
+ if(parent != child) {
+ ++graph[parent].children[child];
+ ++graph[child].parents[child];
+ ++graph[parent].total_with_children;
+ }
+ }
+ std::vector<const line_id*> state;
+ std::vector<std::vector<const line_id*> > pending_children;
+ std::map<const line_id*, node_info>& graph;
+};
+
 int main(int argc, char** argv) {
     const char* input_file_name = 0;
     bool use_call_graph = false;
@@ -113,13 +175,13 @@
     std::map<std::string, int> messages;
     std::string line;
     int total_matches = 0;
- std::ptrdiff_t max_match_length = 0;
+ int max_match_length = 0;
     {
         std::ifstream input(input_file_name);
         while(std::getline(input, line)) {
             boost::smatch match;
- if(boost::regex_match(line, match, warning_message)) {
- max_match_length = (std::max)(max_match_length, match[1].length());
+ if(boost::regex_match(line, match, enter_message)) {
+ max_match_length = boost::numeric_cast<int>((std::max)(max_match_length, match[1].length()));
                 ++messages[match[1]];
                 ++total_matches;
             }
@@ -135,7 +197,9 @@
     std::for_each(copy.begin(), copy.end(), p);
 
     if(use_call_graph) {
+ std::size_t backtrace_depth = 0;
         std::map<const line_id*, node_info> graph;
+ instantiation_state state(graph);
         std::set<line_id> lines;
         typedef std::pair<std::string, int> raw_line;
         BOOST_FOREACH(const raw_line& l, messages) {
@@ -145,76 +209,61 @@
         }
         const line_id* current_instantiation = 0;
         std::ifstream input(input_file_name);
+ int line_number = 0;
 #if defined(_MSC_VER)
         // msvc puts the warning first and follows it with the backtrace.
         while(std::getline(input, line)) {
+ std::cerr << line_number++ << std::endl;
             boost::smatch match;
- if(boost::regex_match(line, match, warning_message)) {
+ if(boost::regex_match(line, match, enter_message)) {
+ // commit the current instantiation
+ if(current_instantiation) {
+ state.add_instantiation(current_instantiation, backtrace_depth);
+ }
+ // start a new instantiation
                 std::string file_and_line(match[1].str());
                 boost::regex_match(file_and_line, match, split_file_and_line);
                 std::string file = match[1];
                 int line = boost::lexical_cast<int>(match[2].str());
                 current_instantiation = &*lines.find(line_id(file, line));
- ++graph[current_instantiation].total_with_children;
- ++graph[current_instantiation].count;
             } else if(boost::regex_match(line, match, call_graph_line)) {
- std::string file = match[1];
- int line = boost::lexical_cast<int>(match[2].str());
- std::set<line_id>::const_iterator pos = lines.lower_bound(line_id(file, line));
- if(pos != lines.end()) {
- if(*pos != line_id(file, line) && pos != lines.begin() && boost::prior(pos)->first == file) {
- --pos;
- }
- } else if(pos != lines.begin()) {
- --pos;
- } else {
- break;
+ ++backtrace_depth;
+ } else if(boost::regex_match(line, match, exit_message)) {
+ // commit the current instantiation
+ if(current_instantiation) {
+ state.add_instantiation(current_instantiation, backtrace_depth);
+ }
+
+ state.finish_instantiation();
+ if(backtrace_depth) {
+ --backtrace_depth;
                 }
- const line_id* parent = &*pos;
- ++graph[current_instantiation].parents[parent];
- ++graph[parent].children[current_instantiation];
- ++graph[parent].total_with_children;
+ current_instantiation = 0;
             }
         }
+ // commit the current instantiation
+ if(current_instantiation) {
+ state.add_instantiation(current_instantiation, backtrace_depth);
+ }
 #elif defined(__GNUC__)
         // gcc puts the backtrace first, and then the warning.
- // so we have to buffer the backtrace until we reach the
- // warning.
- std::vector<std::string> pending_lines;
         while(std::getline(input, line)) {
             boost::smatch match;
- if(boost::regex_match(line, match, warning_message)) {
+ if(boost::regex_match(line, match, enter_message)) {
                 std::string file_and_line(match[1].str());
                 boost::regex_match(file_and_line, match, split_file_and_line);
                 std::string file = match[1];
                 int line = boost::lexical_cast<int>(match[2].str());
                 current_instantiation = &*lines.find(line_id(file, line));
- ++graph[current_instantiation].total_with_children;
- ++graph[current_instantiation].count;
- BOOST_FOREACH(const std::string& line, pending_lines) {
- boost::regex_match(line, match, call_graph_line);
- std::string file = match[1];
- int line = boost::lexical_cast<int>(match[2].str());
- std::set<line_id>::const_iterator pos = lines.lower_bound(line_id(file, line));
- if(pos != lines.end()) {
- if(*pos != line_id(file, line) && pos != lines.begin() && boost::prior(pos)->first == file) {
- --pos;
- }
- } else if(pos != lines.begin()) {
- --pos;
- } else {
- break;
- }
- const line_id* parent = &*pos;
- ++graph[current_instantiation].parents[parent];
- ++graph[parent].children[current_instantiation];
- ++graph[parent].total_with_children;
- }
- pending_lines.clear();
+ ++backtrace_depth;
+ std::cerr << backtrace_depth << std::endl;
+ state.add_instantiation(current_instantiation, backtrace_depth);
+ backtrace_depth = 0;
             } else if(boost::regex_match(line, match, call_graph_line)) {
- pending_lines.push_back(line);
- } else {
- pending_lines.clear();
+ ++backtrace_depth;
+ } else if(boost::regex_match(line, match, exit_message)) {
+ state.finish_instantiation();
+ backtrace_depth = 0;
             }
         }
 #else

Modified: sandbox/tools/profile_templates/template_profiler.hpp
==============================================================================
--- sandbox/tools/profile_templates/template_profiler.hpp (original)
+++ sandbox/tools/profile_templates/template_profiler.hpp 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
@@ -11,7 +11,8 @@
 #define TEMPLATE_PROFILER_HPP_INLUCDED
 
 namespace template_profiler {
- struct incomplete;
+ struct incomplete_enter;
+ struct incomplete_exit;
     template<int N>
     struct int_ {
         enum { value = N };
@@ -21,45 +22,55 @@
     struct make_zero {
         enum { value = 0 };
     };
- extern int value;
+ extern int enter_value;
+ extern int exit_value;
 }
 
 char template_profiler_size_one(...);
 
-#ifdef PROFILE_TEMPLATES
-
 #if defined(_MSC_VER)
- #define PROFILE_TRACER() enum template_profiler_test { template_profiler_value = sizeof(delete ((::template_profiler::incomplete*)0),0) };
+ #define TEMPLATE_PROFILE_ENTER() enum template_profiler_test_enter { template_profiler_value_enter = sizeof(delete ((::template_profiler::incomplete_enter*)0),0) };
+ #define TEMPLATE_PROFILE_EXIT() enum template_profiler_test_exit { template_profiler_value_exit = sizeof(delete ((::template_profiler::incomplete_exit*)0),0) };
 #elif defined(__GNUC__)
     #if (__GNUC__ < 4) || (__GNUC_MINOR__ < 3)
- #define PROFILE_TRACER()\
- struct template_profiler_test {};\
- enum {template_profiler_size = sizeof(template_profiler_size_one(static_cast<template_profiler_test*>(0))) };\
+ #define TEMPLATE_PROFILE_ENTER()\
+ struct template_profiler_test_enter {};\
+ enum {template_profiler_size_enter = sizeof(template_profiler_size_one(static_cast<template_profiler_test*>(0))) };\
+ typedef ::template_profiler::int_<\
+ sizeof(\
+ ::template_profiler::enter_value /\
+ ::template_profiler::make_zero<\
+ ::template_profiler::int_<\
+ template_profiler_size\
+ >\
+ >::value\
+ )\
+ > template_profiler_test_result_enter;
+ #define TEMPLATE_PROFILE_EXIT()\
+ struct template_profiler_test_exit {};\
+ enum {template_profiler_size_exit = sizeof(template_profiler_size_one(static_cast<template_profiler_test*>(0))) };\
         typedef ::template_profiler::int_<\
             sizeof(\
- ::template_profiler::value /\
+ ::template_profiler::exit_value /\
                 ::template_profiler::make_zero<\
                     ::template_profiler::int_<\
                         template_profiler_size\
>\
>::value\
             )\
- > template_profiler_test_result;
+ > template_profiler_test_result_exit;
     #else
         namespace template_profiler {
- __attribute__((deprecated)) int f(int);
- int f(double);
+ __attribute__((deprecated)) int enter(int);
+ int begin(double);
+ __attribute__((deprecated)) int exit(int);
+ int end(double);
         }
- #define PROFILE_TRACER() enum { template_profiler_size = sizeof(::template_profiler::f(1)) };
+ #define TEMPLATE_PROFILE_ENTER() enum { template_profiler_size_enter = sizeof(::template_profiler::enter(1)) };
+ #define TEMPLATE_PROFILE_EXIT() enum { template_profiler_size_exit = sizeof(::template_profiler::exit(1)) };
     #endif
 #else
     #error Unknown compiler
 #endif
 
-#else
-
- #define PROFILE_TRACER()
-
-#endif
-
 #endif

Modified: sandbox/tools/profile_templates/test/test.cpp
==============================================================================
--- sandbox/tools/profile_templates/test/test.cpp (original)
+++ sandbox/tools/profile_templates/test/test.cpp 2009-05-28 19:26:32 EDT (Thu, 28 May 2009)
@@ -1,6 +1,6 @@
 // test.cpp
 //
-// Copyright (c) 2008
+// Copyright (c) 2008-2009
 // Steven Watanabe
 //
 // Distributed under the Boost Software License, Version 1.0. (See
@@ -9,9 +9,35 @@
 
 #include <test.hpp>
 
+struct outer {
+ struct inner {
+ };
+};
+
+template<int N>
+struct inheritence_test
+ :
+ inheritence_test<N - 1>
+ {};
+
+template<>
+struct inheritence_test<0> {};
+
+template<int N>
+struct member_test {
+ typedef typename member_test<N - 1>::type type;
+};
+
+template<>
+struct member_test<0> {
+ typedef void type;
+};
+
 int main() {
     X<int> x1;
     X<char> x2;
     f(1);
     f('a');
+ inheritence_test<5> i_test;
+ member_test<5> m_test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk