Changeset 4707


Ignore:
Timestamp:
11/12/03 21:26:59 (18 years ago)
Author:
piso
Message:

Time profiling.

Location:
trunk/j/src/org/armedbear/lisp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/j/src/org/armedbear/lisp/Lisp.java

    r4673 r4707  
    33 *
    44 * Copyright (C) 2002-2003 Peter Graves
    5  * $Id: Lisp.java,v 1.174 2003-11-07 20:19:49 piso Exp $
     5 * $Id: Lisp.java,v 1.175 2003-11-12 21:26:20 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    3939    public static final Package PACKAGE_EXT =
    4040        Packages.createPackage("EXTENSIONS");
     41    public static final Package PACKAGE_PROF =
     42        Packages.createPackage("PROFILER");
    4143    public static final Package PACKAGE_JAVA =
    4244        Packages.createPackage("JAVA");
     
    5658            PACKAGE_EXT.addNickname("EXT");
    5759            PACKAGE_EXT.usePackage(PACKAGE_CL);
     60            PACKAGE_PROF.addNickname("PROF");
     61            PACKAGE_PROF.usePackage(PACKAGE_CL);
     62            PACKAGE_PROF.usePackage(PACKAGE_EXT);
    5863        }
    5964        catch (Throwable t) {
     
    6671    static {
    6772        PACKAGE_CL.addInitialExports(Exports.COMMON_LISP_SYMBOL_NAMES);
     73        PACKAGE_PROF.addExternalSymbol("SHOW-CALL-COUNTS");
     74        PACKAGE_PROF.addExternalSymbol("PROFILE");
    6875    }
    6976
     
    7885    static final int FTYPE_MACRO            = 2;
    7986    static final int FTYPE_AUTOLOAD         = 3;
     87
     88    public static boolean debug = true;
     89
     90    public static boolean profiling;
     91
     92    public static boolean sampling;
     93
     94    public static volatile boolean sampleNow;
    8095
    8196    // argv must not be null!
     
    94109        LispObject result;
    95110        if (profiling)
    96             fun.incrementCallCount();
     111            if (!sampling)
     112                fun.incrementCallCount();
    97113        switch (argv.length) {
    98114            case 0:
     
    132148        LispObject result;
    133149        if (profiling)
    134             fun.incrementCallCount();
     150            if (!sampling)
     151                fun.incrementCallCount();
    135152        result = fun.execute();
    136153        if (debug)
     
    156173        LispObject result;
    157174        if (profiling)
    158             fun.incrementCallCount();
     175            if (!sampling)
     176                fun.incrementCallCount();
    159177        result = fun.execute(arg);
    160178        if (debug)
     
    181199        LispObject result;
    182200        if (profiling)
    183             fun.incrementCallCount();
     201            if (!sampling)
     202                fun.incrementCallCount();
    184203        result = fun.execute(first, second);
    185204        if (debug)
     
    208227        LispObject result;
    209228        if (profiling)
    210             fun.incrementCallCount();
     229            if (!sampling)
     230                fun.incrementCallCount();
    211231        result = fun.execute(first, second, third);
    212232        if (debug)
     
    253273                    LispObject expander = ((MacroObject)obj).getExpander();
    254274                    if (profiling)
    255                         expander.incrementCallCount();
     275                        if (!sampling)
     276                            expander.incrementCallCount();
    256277                    results[0] = expander.execute(form, env);
    257278                    results[1] = T;
     
    282303        return results[0];
    283304    }
    284 
    285     public static boolean debug = true;
    286305
    287306    private static final Primitive1 INTERACTIVE_EVAL =
     
    338357        throws ConditionThrowable
    339358    {
     359        if (profiling && sampling) {
     360            // FIXME
     361            // This is not exactly the right place to do this. We should
     362            // include the current call as well.
     363            if (sampleNow)
     364                Profiler.sample(thread);
     365        }
    340366        thread.clearValues();
    341367        if (thread.isDestroyed())
     
    364390                    case FTYPE_SPECIAL_OPERATOR: {
    365391                        if (profiling)
    366                             fun.incrementCallCount();
     392                            if (!sampling)
     393                                fun.incrementCallCount();
    367394                        // Don't eval args!
    368395                        return fun.execute(obj.cdr(), env);
     
    381408                                           thread);
    382409                        if (profiling)
    383                             fun.incrementCallCount();
     410                            if (!sampling)
     411                                fun.incrementCallCount();
    384412                        LispObject args = obj.cdr();
    385413                        if (args == NIL)
     
    12621290        public LispObject execute() throws ConditionThrowable
    12631291        {
    1264             debug = true;
    1265             return LispThread.currentThread().nothing();
     1292            final LispThread thread = LispThread.currentThread();
     1293            if (!debug) {
     1294                debug = true;
     1295                thread.resetStack();
     1296            }
     1297            return thread.nothing();
    12661298        }
    12671299    };
     
    12801312    };
    12811313
    1282     private static boolean profiling;
    1283 
    1284     // ### start-profiler
    1285     public static final Primitive0 START_PROFILER =
    1286         new Primitive0("start-profiler", PACKAGE_EXT, true)
    1287     {
    1288         public LispObject execute() throws ConditionThrowable
    1289         {
    1290             CharacterOutputStream out = getStandardOutput();
    1291             out.freshLine();
    1292             if (!profiling) {
    1293                 Package[] packages = Packages.getAllPackages();
    1294                 for (int i = 0; i < packages.length; i++) {
    1295                     Package pkg = packages[i];
    1296                     Symbol[] symbols = pkg.symbols();
    1297                     for (int j = 0; j < symbols.length; j++) {
    1298                         Symbol symbol = symbols[j];
    1299                         LispObject f = symbol.getSymbolFunction();
    1300                         if (f != null)
    1301                             f.setCallCount(0);
    1302                     }
    1303                 }
    1304                 out.writeLine("; Profiling started.");
    1305                 out.flushOutput();
    1306                 profiling = true;
    1307             } else {
    1308                 out.writeLine("; Profiling already enabled.");
    1309                 out.flushOutput();
    1310             }
    1311             return LispThread.currentThread().nothing();
    1312         }
    1313     };
    1314 
    1315     // ### stop-profiler
    1316     public static final Primitive0 STOP_PROFILER =
    1317         new Primitive0("stop-profiler", PACKAGE_EXT, true)
    1318     {
    1319         public LispObject execute() throws ConditionThrowable
    1320         {
    1321             CharacterOutputStream out = getStandardOutput();
    1322             out.freshLine();
    1323             if (profiling) {
    1324                 profiling = false;
    1325                 out.writeLine("; Profiling stopped.");
    1326             } else
    1327                 out.writeLine("; Profiling not enabled.");
    1328             out.flushOutput();
    1329             return LispThread.currentThread().nothing();
    1330         }
    1331     };
    1332 
    13331314    // ### t
    13341315    public static final Symbol T = PACKAGE_CL.addExternalSymbol("T");
     
    15651546        exportConstant("LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT", PACKAGE_CL,
    15661547                       new LispFloat(- Double.MIN_VALUE));
     1548
     1549    // Profiler.
     1550    public static final Symbol _GRANULARITY_ =
     1551        exportSpecial("*GRANULARITY*", PACKAGE_PROF, new Fixnum(1));
    15671552
    15681553    private static final void loadClass(String className)
  • trunk/j/src/org/armedbear/lisp/profiler.lisp

    r2980 r4707  
    22;;;
    33;;; Copyright (C) 2003 Peter Graves
    4 ;;; $Id: profiler.lisp,v 1.6 2003-07-17 17:20:18 piso Exp $
     4;;; $Id: profiler.lisp,v 1.7 2003-11-12 21:26:59 piso Exp $
    55;;;
    66;;; This program is free software; you can redistribute it and/or
     
    1818;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    1919
    20 (defun show-call-counts ()
    21   (let ((syms (list-calls)))
    22     (setf syms (sort syms #'<
    23                      :key #'(lambda (x) (sys::%call-count (fdefinition x)))))
    24     (dolist (sym syms)
    25       (show-call-count-for-symbol sym)))
    26   (values))
     20(in-package "PROFILER")
     21
     22;; SHOW-CALL-COUNTS and PROFILE are exported in Lisp.java.
    2723
    2824;; Returns list of all symbols with non-zero call counts.
     
    3834    result))
    3935
    40 (defun show-call-count-for-symbol (sym)
    41   (format t "~A ~A~%" sym (sys::%call-count (fdefinition sym))))
     36(defun show-call-count-for-symbol (sym max-count)
     37  (let ((count (sys::%call-count (fdefinition sym))))
     38    (if max-count
     39        (format t "~A ~A (~A%)~%" sym count
     40                (/ (round (/ (* count 10000.0) max-count)) 100.0))
     41        (format t "~A ~A~%" sym count))))
     42
     43(defun show-call-counts ()
     44  (let ((syms (list-calls)))
     45    (setf syms (sort syms #'<
     46                     :key #'(lambda (x) (sys::%call-count (fdefinition x)))))
     47    (let* ((last-sym (car (last syms)))
     48           (max-count (if last-sym
     49                          (sys::%call-count (fdefinition last-sym))
     50                          nil)))
     51      (when (zerop max-count)
     52        (setf max-count nil))
     53      (dolist (sym syms)
     54        (show-call-count-for-symbol sym max-count))))
     55  (values))
    4256
    4357(defmacro profile (&rest forms)
Note: See TracChangeset for help on using the changeset viewer.