diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index a0e11f8..f4b0316 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -2768,7 +2768,9 @@
         indent() << "if (_iprot && _oprot) {" << endl <<
         indent() << "  return process_" << tfunction->get_name() <<
         "(seqid, _iprot, _oprot, callContext);" << endl <<
-        indent() << "}" << endl << endl;
+        indent() << "}" << endl <<
+        indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << endl <<
+        indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl << endl;
     }
 
     string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args";
@@ -2934,7 +2936,9 @@
         indent() << "if (_iprot && _oprot) {" << endl <<
         indent() << "  return process_" << tfunction->get_name() <<
         "(cob, seqid, _iprot, _oprot);" << endl <<
-        indent() << "}" << endl << endl;
+        indent() << "}" << endl <<
+        indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << endl <<
+        indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl << endl;
     }
 
     out <<
@@ -3066,7 +3070,9 @@
           indent() << "if (_oprot) {" << endl <<
           indent() << "  return return_" << tfunction->get_name() <<
           "(cob, seqid, _oprot, ctx" << ret_arg_name << ");" << endl <<
-          indent() << "}" << endl << endl;
+          indent() << "}" << endl <<
+          indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" <<
+          endl << endl;
       }
 
       out <<
@@ -3124,7 +3130,9 @@
           indent() << "if (_oprot) {" << endl <<
           indent() << "  return throw_" << tfunction->get_name() <<
           "(cob, seqid, _oprot, ctx, _throw);" << endl <<
-          indent() << "}" << endl << endl;
+          indent() << "}" << endl <<
+          indent() << "  T_GENERIC_PROTOCOL(this, oprot, _oprot);" <<
+          endl << endl;
       }
 
       out <<
diff --git a/contrib/parse_profiling.py b/contrib/parse_profiling.py
new file mode 100755
index 0000000..52d2211
--- /dev/null
+++ b/contrib/parse_profiling.py
@@ -0,0 +1,310 @@
+#!/usr/bin/env python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+"""
+This script can be used to make the output from
+apache::thrift::profile_print_info() more human-readable.
+
+It translates each executable file name and address into the corresponding
+source file name, line number, and function name.  By default, it also
+demangles C++ symbol names.
+"""
+
+import optparse
+import os
+import re
+import subprocess
+import sys
+
+
+class AddressInfo(object):
+    """
+    A class to store information about a particular address in an object file.
+    """
+    def __init__(self, obj_file, address):
+        self.objectFile = obj_file
+        self.address = address
+        self.sourceFile = None
+        self.sourceLine = None
+        self.funtion = None
+
+
+g_addrs_by_filename = {}
+def get_address(filename, address):
+    """
+    Retrieve an AddressInfo object for the specified object file and address.
+
+    Keeps a global list of AddressInfo objects.  Two calls to get_address()
+    with the same filename and address will always return the same AddressInfo
+    object.
+    """
+    global g_addrs_by_filename
+    try:
+        by_address = g_addrs_by_filename[filename]
+    except KeyError:
+        by_address = {}
+        g_addrs_by_filename[filename] = by_address
+
+    try:
+        addr_info = by_address[address]
+    except KeyError:
+        addr_info = AddressInfo(filename, address)
+        by_address[address] = addr_info
+    return addr_info
+
+
+def translate_file_addresses(filename, addresses, options):
+    """
+    Use addr2line to look up information for the specified addresses.
+    All of the addresses must belong to the same object file.
+    """
+    # Do nothing if we can't find the file
+    if not os.path.isfile(filename):
+        return
+
+    args = ['addr2line']
+    if options.printFunctions:
+        args.append('-f')
+    args.extend(['-e', filename])
+
+    proc = subprocess.Popen(args, stdin=subprocess.PIPE,
+                            stdout=subprocess.PIPE)
+    for address in addresses:
+        assert address.objectFile == filename
+        proc.stdin.write(address.address + '\n')
+
+        if options.printFunctions:
+            function = proc.stdout.readline()
+            function = function.strip()
+            if not function:
+                raise Exception('unexpected EOF from addr2line')
+            address.function = function
+
+        file_and_line = proc.stdout.readline()
+        file_and_line = file_and_line.strip()
+        if not file_and_line:
+            raise Exception('unexpected EOF from addr2line')
+        idx = file_and_line.rfind(':')
+        if idx < 0:
+            msg = 'expected file and line number from addr2line; got %r' % \
+                    (file_and_line,)
+            msg += '\nfile=%r, address=%r' % (filename, address.address)
+            raise Exception(msg)
+
+        address.sourceFile = file_and_line[:idx]
+        address.sourceLine = file_and_line[idx+1:]
+
+    (remaining_out, cmd_err) = proc.communicate()
+    retcode = proc.wait()
+    if retcode != 0:
+        raise subprocess.CalledProcessError(retcode, args)
+
+
+def lookup_addresses(options):
+    """
+    Look up source file information for all of the addresses currently stored
+    in the global list of AddressInfo objects.
+    """
+    global g_addrs_by_filename
+    for (file, addresses) in g_addrs_by_filename.items():
+        translate_file_addresses(file, addresses.values(), options)
+
+
+class Entry(object):
+    """
+    An entry in the thrift profile output.
+    Contains a header line, and a backtrace.
+    """
+    def __init__(self, header):
+        self.header = header
+        self.bt = []
+
+    def addFrame(self, filename, address):
+        # If libc was able to determine the symbols names, the filename
+        # argument will be of the form <filename>(<function>+<offset>)
+        # So, strip off anything after the last '('
+        idx = filename.rfind('(')
+        if idx >= 0:
+            filename = filename[:idx]
+
+        addr = get_address(filename, address)
+        self.bt.append(addr)
+
+    def write(self, f, options):
+        f.write(self.header)
+        f.write('\n')
+        n = 0
+        for address in self.bt:
+            f.write('  #%-2d %s:%s\n' % (n, address.sourceFile,
+                                         address.sourceLine))
+            n += 1
+            if options.printFunctions:
+                if address.function:
+                    f.write('      %s\n' % (address.function,))
+                else:
+                    f.write('      ??\n')
+
+
+def process_file(in_file, out_file, options):
+    """
+    Read thrift profile output from the specified input file, and print
+    prettier information on the output file.
+    """
+    #
+    # A naive approach would be to read the input line by line,
+    # and each time we come to a filename and address, pass it to addr2line
+    # and print the resulting information.  Unfortunately, addr2line can be
+    # quite slow, especially with large executables.
+    #
+    # This approach is much faster.  We read in all of the input, storing
+    # the addresses in each file that need to be resolved.  We then call
+    # addr2line just once for each file.  This is much faster than calling
+    # addr2line once per address.
+    #
+
+    virt_call_regex = re.compile(r'^\s*T_VIRTUAL_CALL: (\d+) calls on (.*):$')
+    gen_prot_regex = re.compile(
+            r'^\s*T_GENERIC_PROTOCOL: (\d+) calls to (.*) with a (.*):$')
+    bt_regex = re.compile(r'^\s*#(\d+)\s*(.*) \[(0x[0-9A-Za-z]+)\]$')
+
+    # Parse all of the input, and store it as Entry objects
+    entries = []
+    current_entry = None
+    while True:
+        line = in_file.readline()
+        if not line:
+            break
+
+        if line == '\n' or line.startswith('Thrift virtual call info:'):
+            continue
+
+        virt_call_match = virt_call_regex.match(line)
+        if virt_call_match:
+            num_calls = int(virt_call_match.group(1))
+            type_name = virt_call_match.group(2)
+            if options.cxxfilt:
+                # Type names reported by typeid() are internal names.
+                # By default, c++filt doesn't demangle internal type names.
+                # (Some versions of c++filt have a "-t" option to enable this.
+                # Other versions don't have this argument, but demangle type
+                # names passed as an argument, but not on stdin.)
+                #
+                # If the output is being filtered through c++filt, prepend
+                # "_Z" to the type name to make it look like an external name.
+                type_name = '_Z' + type_name
+            header = 'T_VIRTUAL_CALL: %d calls on "%s"' % \
+                    (num_calls, type_name)
+            if current_entry is not None:
+                entries.append(current_entry)
+            current_entry = Entry(header)
+            continue
+
+        gen_prot_match = gen_prot_regex.match(line)
+        if gen_prot_match:
+            num_calls = int(gen_prot_match.group(1))
+            type_name1 = gen_prot_match.group(2)
+            type_name2 = gen_prot_match.group(3)
+            if options.cxxfilt:
+                type_name1 = '_Z' + type_name1
+                type_name2 = '_Z' + type_name2
+            header = 'T_GENERIC_PROTOCOL: %d calls to "%s" with a "%s"' % \
+                    (num_calls, type_name1, type_name2)
+            if current_entry is not None:
+                entries.append(current_entry)
+            current_entry = Entry(header)
+            continue
+
+        bt_match = bt_regex.match(line)
+        if bt_match:
+            if current_entry is None:
+                raise Exception('found backtrace frame before entry header')
+            frame_num = int(bt_match.group(1))
+            filename = bt_match.group(2)
+            address = bt_match.group(3)
+            current_entry.addFrame(filename, address)
+            continue
+
+        raise Exception('unexpected line in input: %r' % (line,))
+
+    # Add the last entry we were processing to the list
+    if current_entry is not None:
+        entries.append(current_entry)
+        current_entry = None
+
+    # Look up all of the addresses
+    lookup_addresses(options)
+
+    # Print out the entries, now that the information has been translated
+    for entry in entries:
+        entry.write(out_file, options)
+        out_file.write('\n')
+
+
+def start_cppfilt():
+    (read_pipe, write_pipe) = os.pipe()
+
+    # Fork.  Run c++filt in the parent process,
+    # and then continue normal processing in the child.
+    pid = os.fork()
+    if pid == 0:
+        # child
+        os.dup2(write_pipe, sys.stdout.fileno())
+        os.close(read_pipe)
+        os.close(write_pipe)
+        return
+    else:
+        # parent
+        os.dup2(read_pipe, sys.stdin.fileno())
+        os.close(read_pipe)
+        os.close(write_pipe)
+
+        cmd = ['c++filt']
+        os.execvp(cmd[0], cmd)
+
+
+def main(argv):
+    parser = optparse.OptionParser(usage='%prog [options] [<file>]')
+    parser.add_option('--no-functions', help='Don\'t print function names',
+                      dest='printFunctions', action='store_false',
+                      default=True)
+    parser.add_option('--no-demangle',
+                      help='Don\'t demangle C++ symbol names',
+                      dest='cxxfilt', action='store_false',
+                      default=True)
+
+    (options, args) = parser.parse_args(argv[1:])
+    num_args = len(args)
+    if num_args == 0:
+        in_file = sys.stdin
+    elif num_args == 1:
+        in_file = open(argv[1], 'r')
+    else:
+        parser.print_usage(sys.stderr)
+        print >> sys.stderr, 'trailing arguments: %s' % (' '.join(args[1:],))
+        return 1
+
+    if options.cxxfilt:
+        start_cppfilt()
+
+    process_file(in_file, sys.stdout, options)
+
+
+if __name__ == '__main__':
+    rc = main(sys.argv)
+    sys.exit(rc)
diff --git a/lib/cpp/src/TLogging.h b/lib/cpp/src/TLogging.h
index 54cccbe..2c23f0a 100644
--- a/lib/cpp/src/TLogging.h
+++ b/lib/cpp/src/TLogging.h
@@ -162,24 +162,38 @@
 
 
 /**
- * T_GLOBAL_DEBUG_VIRTUAL = 0: normal operation,
- *                             virtual call debug messages disabled
- * T_GLOBAL_DEBUG_VIRTUAL = 1: log a debug messages whenever an
- *                             avoidable virtual call is made
+ * T_GLOBAL_DEBUG_VIRTUAL = 0 or unset: normal operation,
+ *                                      virtual call debug messages disabled
+ * T_GLOBAL_DEBUG_VIRTUAL = 1:          log a debug messages whenever an
+ *                                      avoidable virtual call is made
+ * T_GLOBAL_DEBUG_VIRTUAL = 2:          record detailed info that can be
+ *                                      printed by calling
+ *                                      apache::thrift::profile_print_info()
  */
-#define T_GLOBAL_DEBUG_VIRTUAL 0
-
-/**
- * Log a message indicating that a virtual function call is being made.
- *
- * This should be disabled during normal use.  It is intended to be used
- * only to help debug serialization performance.
- */
-#if T_GLOBAL_DEBUG_VIRTUAL > 0
-  #define T_VIRTUAL_CALL()                                              \
+#if T_GLOBAL_DEBUG_VIRTUAL > 1
+  #define T_VIRTUAL_CALL()                                                \
+    ::apache::thrift::profile_virtual_call(typeid(*this))
+  #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
+    do {                                                                  \
+      if (!(specific_prot)) {                                             \
+        ::apache::thrift::profile_generic_protocol(                     \
+            typeid(*template_class), typeid(*generic_prot));              \
+      }                                                                   \
+    } while (0)
+#elif T_GLOBAL_DEBUG_VIRTUAL == 1
+  #define T_VIRTUAL_CALL()                                                \
     fprintf(stderr,"[%s,%d] virtual call\n", __FILE__, __LINE__)
+  #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
+    do {                                                                  \
+      if (!(specific_prot)) {                                             \
+        fprintf(stderr,                                                   \
+                "[%s,%d] failed to cast to specific protocol type\n",     \
+                __FILE__, __LINE__);                                      \
+      }                                                                   \
+    } while (0)
 #else
   #define T_VIRTUAL_CALL()
+  #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot)
 #endif
 
 #endif // #ifndef _THRIFT_TLOGGING_H_
diff --git a/lib/cpp/src/Thrift.h b/lib/cpp/src/Thrift.h
index cb7d55a..a8bf2a8 100644
--- a/lib/cpp/src/Thrift.h
+++ b/lib/cpp/src/Thrift.h
@@ -36,6 +36,7 @@
 #include <set>
 #include <vector>
 #include <exception>
+#include <typeinfo>
 
 #include "TLogging.h"
 
@@ -134,6 +135,15 @@
   return new TExceptionWrapper<E>(e);
 }
 
+#if T_GLOBAL_DEBUG_VIRTUAL > 1
+void profile_virtual_call(const std::type_info& info);
+void profile_generic_protocol(const std::type_info& template_type,
+                              const std::type_info& prot_type);
+void profile_print_info(FILE *f);
+void profile_print_info();
+void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f);
+#endif
+
 }} // apache::thrift
 
 #endif // #ifndef _THRIFT_THRIFT_H_
diff --git a/lib/cpp/src/VirtualProfiling.cpp b/lib/cpp/src/VirtualProfiling.cpp
new file mode 100644
index 0000000..0b023af
--- /dev/null
+++ b/lib/cpp/src/VirtualProfiling.cpp
@@ -0,0 +1,455 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <Thrift.h>
+
+// Do nothing if virtual call profiling is not enabled
+#if T_GLOBAL_DEBUG_VIRTUAL > 1
+
+// TODO: This code only works with g++ (since we rely on the fact
+// that all std::type_info instances referring to a particular type
+// always return the exact same pointer value from name().)
+#ifndef __GNUG__
+#error "Thrift virtual function profiling currently only works with gcc"
+#endif // !__GNUG__
+
+// TODO: We also require glibc for the backtrace() and backtrace_symbols()
+// functions.
+#ifndef __GLIBC__
+#error "Thrift virtual function profiling currently requires glibc"
+#endif // !__GLIBC__
+
+
+#include <concurrency/Mutex.h>
+
+#include <ext/hash_map>
+#include <execinfo.h>
+#include <stdio.h>
+
+namespace apache { namespace thrift {
+
+using ::apache::thrift::concurrency::Mutex;
+using ::apache::thrift::concurrency::Guard;
+
+static const unsigned int MAX_STACK_DEPTH = 15;
+
+/**
+ * A stack trace
+ */
+class Backtrace {
+ public:
+  Backtrace(int skip = 0);
+  Backtrace(Backtrace const &bt);
+
+  void operator=(Backtrace const &bt) {
+    numCallers_ = bt.numCallers_;
+    if (numCallers_ >= 0) {
+      memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
+    }
+  }
+
+  bool operator==(Backtrace const &bt) const {
+    return (cmp(bt) == 0);
+  }
+
+  size_t hash() const {
+    intptr_t ret = 0;
+    for (int n = 0; n < numCallers_; ++n) {
+      ret ^= reinterpret_cast<intptr_t>(callers_[n]);
+    }
+    return static_cast<size_t>(ret);
+  }
+
+  int cmp(Backtrace const& bt) const {
+    int depth_diff = (numCallers_ - bt.numCallers_);
+    if (depth_diff != 0) {
+      return depth_diff;
+    }
+
+    for (int n = 0; n < numCallers_; ++n) {
+      int diff = reinterpret_cast<intptr_t>(callers_[n]) -
+        reinterpret_cast<intptr_t>(bt.callers_[n]);
+      if (diff != 0) {
+        return diff;
+      }
+    }
+
+    return 0;
+  }
+
+  void print(FILE *f, int indent=0, int start=0) const {
+    char **strings = backtrace_symbols(callers_, numCallers_);
+    if (strings) {
+      start += skip_;
+      if (start < 0) {
+        start = 0;
+      }
+      for (int n = start; n < numCallers_; ++n) {
+        fprintf(f, "%*s#%-2d %s\n", indent, "", n, strings[n]);
+      }
+      free(strings);
+    } else {
+      fprintf(f, "%*s<failed to determine symbols>\n", indent, "");
+    }
+  }
+
+  int getDepth() const {
+    return numCallers_ - skip_;
+  }
+
+  void *getFrame(int index) const {
+    int adjusted_index = index + skip_;
+    if (adjusted_index < 0 || adjusted_index >= numCallers_) {
+      return NULL;
+    }
+    return callers_[adjusted_index];
+  }
+
+ private:
+  void *callers_[MAX_STACK_DEPTH];
+  int numCallers_;
+  int skip_;
+};
+
+// Define the constructors non-inline, so they consistently add a single
+// frame to the stack trace, regardless of whether optimization is enabled
+Backtrace::Backtrace(int skip)
+  : skip_(skip + 1) // ignore the constructor itself
+{
+  numCallers_ = backtrace(callers_, MAX_STACK_DEPTH);
+  if (skip_ > numCallers_) {
+    skip_ = numCallers_;
+  }
+}
+
+Backtrace::Backtrace(Backtrace const &bt)
+  : numCallers_(bt.numCallers_)
+  , skip_(bt.skip_) {
+  if (numCallers_ >= 0) {
+    memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
+  }
+}
+
+/**
+ * A backtrace, plus one or two type names
+ */
+class Key {
+ public:
+  class Hash {
+   public:
+    size_t operator()(Key const& k) const {
+      return k.hash();
+    }
+  };
+
+  Key(const Backtrace* bt, const std::type_info& type_info)
+    : backtrace_(bt)
+    , typeName1_(type_info.name())
+    , typeName2_(NULL) {
+  }
+
+  Key(const Backtrace* bt, const std::type_info& type_info1,
+      const std::type_info& type_info2)
+    : backtrace_(bt)
+    , typeName1_(type_info1.name())
+    , typeName2_(type_info2.name()) {
+  }
+
+  Key(const Key& k)
+    : backtrace_(k.backtrace_)
+    , typeName1_(k.typeName1_)
+    , typeName2_(k.typeName2_) {
+  }
+
+  void operator=(const Key& k) {
+    backtrace_ = k.backtrace_;
+    typeName1_ = k.typeName1_;
+    typeName2_ = k.typeName2_;
+  }
+
+  const Backtrace* getBacktrace() const {
+    return backtrace_;
+  }
+
+  const char* getTypeName() const {
+    return typeName1_;
+  }
+
+  const char* getTypeName2() const {
+    return typeName2_;
+  }
+
+  void makePersistent() {
+    // Copy the Backtrace object
+    backtrace_ = new Backtrace(*backtrace_);
+
+    // NOTE: We don't copy the type name.
+    // The GNU libstdc++ implementation of type_info::name() returns a value
+    // that will be valid for the lifetime of the program.  (Although the C++
+    // standard doesn't guarantee this will be true on all implementations.)
+  }
+
+  /**
+   * Clean up memory allocated by makePersistent()
+   *
+   * Should only be invoked if makePersistent() has previously been called.
+   * The Key should no longer be used after cleanup() is called.
+   */
+  void cleanup() {
+    delete backtrace_;
+    backtrace_ = NULL;
+  }
+
+  int cmp(const Key& k) const {
+    int ret = backtrace_->cmp(*k.backtrace_);
+    if (ret != 0) {
+      return ret;
+    }
+
+    // NOTE: We compare just the name pointers.
+    // With GNU libstdc++, every type_info object for the same type points to
+    // exactly the same name string.  (Although this isn't guaranteed by the
+    // C++ standard.)
+    ret = k.typeName1_ - typeName1_;
+    if (ret != 0) {
+      return ret;
+    }
+    return k.typeName2_ - typeName2_;
+  }
+
+  bool operator==(const Key& k) const {
+    return cmp(k) == 0;
+  }
+
+  size_t hash() const {
+    // NOTE: As above, we just use the name pointer value.
+    // Works with GNU libstdc++, but not guaranteed to be correct on all
+    // implementations.
+    return backtrace_->hash() ^
+      reinterpret_cast<size_t>(typeName1_) ^
+      reinterpret_cast<size_t>(typeName2_);
+  }
+
+ private:
+  const Backtrace* backtrace_;
+  const char* typeName1_;
+  const char* typeName2_;
+};
+
+/**
+ * A functor that determines which of two BacktraceMap entries
+ * has a higher count.
+ */
+class CountGreater {
+ public:
+  bool operator()(std::pair<Key, size_t> bt1,
+                  std::pair<Key, size_t> bt2) const {
+    return bt1.second > bt2.second;
+  }
+};
+
+typedef __gnu_cxx::hash_map<Key, size_t, Key::Hash> BacktraceMap;
+
+/**
+ * A map describing how many times T_VIRTUAL_CALL() has been invoked.
+ */
+BacktraceMap virtual_calls;
+Mutex virtual_calls_mutex;
+
+/**
+ * A map describing how many times T_GENERIC_PROTOCOL() has been invoked.
+ */
+BacktraceMap generic_calls;
+Mutex generic_calls_mutex;
+
+
+void _record_backtrace(BacktraceMap* map, const Mutex& mutex, Key *k) {
+  Guard guard(mutex);
+
+  BacktraceMap::iterator it = map->find(*k);
+  if (it == map->end()) {
+    k->makePersistent();
+    map->insert(std::make_pair(*k, 1));
+  } else {
+    // increment the count
+    // NOTE: we could assert if it->second is 0 afterwards, since that would
+    // mean we've wrapped.
+    ++(it->second);
+  }
+}
+
+/**
+ * Record an unnecessary virtual function call.
+ *
+ * This method is invoked by the T_VIRTUAL_CALL() macro.
+ */
+void profile_virtual_call(const std::type_info& type) {
+  int const skip = 1; // ignore this frame
+  Backtrace bt(skip);
+  Key k(&bt, type);
+  _record_backtrace(&virtual_calls, virtual_calls_mutex, &k);
+}
+
+/**
+ * Record a call to a template processor with a protocol that is not the one
+ * specified in the template parameter.
+ *
+ * This method is invoked by the T_GENERIC_PROTOCOL() macro.
+ */
+void profile_generic_protocol(const std::type_info& template_type,
+                              const std::type_info& prot_type) {
+  int const skip = 1; // ignore this frame
+  Backtrace bt(skip);
+  Key k(&bt, template_type, prot_type);
+  _record_backtrace(&generic_calls, generic_calls_mutex, &k);
+}
+
+/**
+ * Print the recorded profiling information to the specified file.
+ */
+void profile_print_info(FILE* f) {
+  typedef std::vector< std::pair<Key, size_t> > BacktraceVector;
+
+  CountGreater is_greater;
+
+  // Grab both locks for the duration of the print operation,
+  // to ensure the output is a consistent snapshot of a single point in time
+  Guard generic_calls_guard(generic_calls_mutex);
+  Guard virtual_calls_guard(virtual_calls_mutex);
+
+  // print the info from generic_calls, sorted by frequency
+  //
+  // We print the generic_calls info ahead of virtual_calls, since it is more
+  // useful in some cases.  All T_GENERIC_PROTOCOL calls can be eliminated
+  // from most programs.  Not all T_VIRTUAL_CALLs will be eliminated by
+  // converting to templates.
+  BacktraceVector gp_sorted(generic_calls.begin(), generic_calls.end());
+  std::sort(gp_sorted.begin(), gp_sorted.end(), is_greater);
+
+  for (BacktraceVector::const_iterator it = gp_sorted.begin();
+       it != gp_sorted.end();
+       ++it) {
+    Key const &key = it->first;
+    size_t const count = it->second;
+    fprintf(f, "T_GENERIC_PROTOCOL: %zu calls to %s with a %s:\n",
+            count, key.getTypeName(), key.getTypeName2());
+    key.getBacktrace()->print(f, 2);
+    fprintf(f, "\n");
+  }
+
+  // print the info from virtual_calls, sorted by frequency
+  BacktraceVector vc_sorted(virtual_calls.begin(), virtual_calls.end());
+  std::sort(vc_sorted.begin(), vc_sorted.end(), is_greater);
+
+  for (BacktraceVector::const_iterator it = vc_sorted.begin();
+       it != vc_sorted.end();
+       ++it) {
+    Key const &key = it->first;
+    size_t const count = it->second;
+    fprintf(f, "T_VIRTUAL_CALL: %zu calls on %s:\n", count, key.getTypeName());
+    key.getBacktrace()->print(f, 2);
+    fprintf(f, "\n");
+  }
+}
+
+/**
+ * Print the recorded profiling information to stdout.
+ */
+void profile_print_info() {
+  profile_print_info(stdout);
+}
+
+/**
+ * Write a BacktraceMap as Google CPU profiler binary data.
+ */
+static void profile_write_pprof_file(FILE* f, BacktraceMap const& map) {
+  // Write the header
+  uintptr_t header[5] = { 0, 3, 0, 0, 0 };
+  fwrite(&header, sizeof(header), 1, f);
+
+  // Write the profile records
+  for (BacktraceMap::const_iterator it = map.begin(); it != map.end(); ++it) {
+    uintptr_t count = it->second;
+    fwrite(&count, sizeof(count), 1, f);
+
+    Backtrace const* bt = it->first.getBacktrace();
+    uintptr_t num_pcs = bt->getDepth();
+    fwrite(&num_pcs, sizeof(num_pcs), 1, f);
+
+    for (uintptr_t n = 0; n < num_pcs; ++n) {
+      void* pc = bt->getFrame(n);
+      fwrite(&pc, sizeof(pc), 1, f);
+    }
+  }
+
+  // Write the trailer
+  uintptr_t trailer[3] = { 0, 1, 0 };
+  fwrite(&trailer, sizeof(trailer), 1, f);
+
+  // Write /proc/self/maps
+  // TODO(simpkins): This only works on linux
+  FILE *proc_maps = fopen("/proc/self/maps", "r");
+  if (proc_maps) {
+    uint8_t buf[4096];
+    while (true) {
+      size_t bytes_read = fread(buf, 1, sizeof(buf), proc_maps);
+      if (bytes_read == 0) {
+        break;
+      }
+      fwrite(buf, 1, bytes_read, f);
+    }
+    fclose(proc_maps);
+  }
+}
+
+/**
+ * Write the recorded profiling information as pprof files.
+ *
+ * This writes the information using the Google CPU profiler binary data
+ * format, so it can be analyzed with pprof.  Note that information about the
+ * protocol/transport data types cannot be stored in this file format.
+ *
+ * See http://code.google.com/p/google-perftools/ for more details.
+ *
+ * @param gen_calls_f     The information about calls to
+ *                        profile_generic_protocol() will be written to this
+ *                        file.
+ * @param virtual_calls_f The information about calls to
+ *                        profile_virtual_call() will be written to this file.
+ */
+void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f) {
+  typedef std::vector< std::pair<Key, size_t> > BacktraceVector;
+
+  CountGreater is_greater;
+
+  // Grab both locks for the duration of the print operation,
+  // to ensure the output is a consistent snapshot of a single point in time
+  Guard generic_calls_guard(generic_calls_mutex);
+  Guard virtual_calls_guard(virtual_calls_mutex);
+
+  // write the info from generic_calls
+  profile_write_pprof_file(gen_calls_f, generic_calls);
+
+  // write the info from virtual_calls
+  profile_write_pprof_file(virtual_calls_f, virtual_calls);
+}
+
+}} // apache::thrift
+
+#endif // T_GLOBAL_PROFILE_VIRTUAL > 0
