This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: REPL commands


* Per Bothner [2009-07-16 22:52+0200] writes:


> These seem like they might be useful - but they need to be doucmented.

OK, the same again with a patch to the manual:

Index: gnu/kawa/slib/repl_commands.scm
===================================================================
--- gnu/kawa/slib/repl_commands.scm	(revision 0)
+++ gnu/kawa/slib/repl_commands.scm	(revision 0)
@@ -0,0 +1,111 @@
+;; repl_commands.scm --- "commands" to be invoked from the REPL
+;; License: Public Domain
+
+(module-export time gc room apropos)
+
+(module-static #t)
+
+(module-compile-options
+ warn-invoke-unknown-method: #t
+ warn-undefined-variable: #t
+ )
+
+;; Call FUN for each element in ITER.
+(define (each (iter java.lang.Iterable) (fun function))
+  (let ((iter :: java.util.Iterator (iter:iterator)))
+    (do ()
+	((not (iter:hasNext)))
+      (fun (iter:next)))))
+
+;; (time FORM) => RESULT 
+;; Evaluate FORM and print various timing data.
+;; Return the result of the evaluating FORM.
+(define-syntax time
+  (syntax-rules ()
+    ((time form)
+     (%time (lambda () form)))))
+
+(define (%time (fun function))
+  (define-alias <mf> java.lang.management.ManagementFactory)
+  (define-alias <gc> java.lang.management.GarbageCollectorMXBean)
+  (let* ((gcs <mf>:GarbageCollectorMXBeans)
+         (mem <mf>:MemoryMXBean)
+         (jit <mf>:CompilationMXBean)
+         (oldjit jit:TotalCompilationTime)
+         (oldgc (let ((alist '()))
+		  (each gcs (lambda ((gc <gc>))
+			      (set! alist `((,gc ,gc:CollectionCount 
+						 ,gc:CollectionTime)
+					    . ,alist))))
+		  alist))
+         (oldheap mem:HeapMemoryUsage:Used)
+         (oldnonheap mem:NonHeapMemoryUsage:Used)
+         (start (java.lang.System:nanoTime))
+         (values (fun))
+         (end (java.lang.System:nanoTime))
+         (newheap mem:HeapMemoryUsage:Used)
+         (newnonheap mem:NonHeapMemoryUsage:Used)
+	 (newjit jit:TotalCompilationTime))
+    (format #t "~&")
+    (format #t "; JIT compilation: ~:d ms (~:d ms total)\n" 
+	    (- newjit oldjit) newjit)
+    (each gcs (lambda ((gc <gc>))
+		(apply (lambda (count time)
+			 (format #t "; GC ~a: ~:d ms (~d collections)\n"
+				 gc:Name 
+				 (- gc:CollectionTime time)
+				 (- gc:CollectionCount count)))
+		       (cdr (assoc gc oldgc)))))
+    (format #t "; Heap: ~@:d (~:d)\n" (- newheap oldheap) newheap)
+    (format #t "; Non-Heap: ~@:d (~:d)\n" (- newnonheap oldnonheap) newnonheap)
+    (format #t "; Elapsed time: ~:d ms\n" (/ (- end start) 1000000))
+    values))
+
+
+;; Initiate a garbage collection.
+;; If the keyword argument VERBOSE is true (the default), print various
+;; GC statistics.
+(define (gc #!key (verbose #t))
+  (let ((mem java.lang.management.ManagementFactory:MemoryMXBean))
+    (if (not verbose)
+	(mem:gc)
+	(let* ((oldheap mem:HeapMemoryUsage:Used)
+	       (oldnonheap mem:NonHeapMemoryUsage:Used)
+	       (oldverbose (mem:isVerbose))
+	       (_ (begin
+		    (if verbose (mem:setVerbose verbose))
+		    (mem:gc)
+		    (mem:setVerbose oldverbose)))
+	       (newheap mem:HeapMemoryUsage:Used)
+	       (newnonheap mem:NonHeapMemoryUsage:Used))
+	  (format #t "; heap: ~@:d (~:d) non-heap: ~@:d (~:d)\n"
+		  (- newheap oldheap) newheap 
+		  (- oldnonheap newnonheap) newnonheap)))))
+
+;; Print information about the memory system.
+(define (room)
+  (let* ((pools java.lang.management.ManagementFactory:MemoryPoolMXBeans)
+         (mem java.lang.management.ManagementFactory:MemoryMXBean)
+         (heap mem:HeapMemoryUsage)
+         (nonheap mem:NonHeapMemoryUsage))
+    (format #t "; Memory Pools\n")
+    (each pools (lambda ((p java.lang.management.MemoryPoolMXBean))
+		  (format #t "~&; ~a~1,16t: ~10:d\n" p:Name p:Usage:Used)))
+    (format #t ";\n")
+    (format #t "; Heap~1,16t: ~10:d (max ~10:d) \n" heap:Used heap:Max)
+    (format #t "; Non-Heap~1,16t: ~10:d (max ~10:d)\n" 
+	    nonheap:Used nonheap:Max)))
+
+;; Print bindings matching PATTERN.
+(define (apropos (pattern string)
+		 #!key (env :: gnu.mapping.Environment
+			    (interaction-environment)))
+  (let ((iter (env:enumerateAllLocations)))
+    (do ()
+	((not (iter:hasNext)))
+      (let ((loc (iter:nextLocation)))
+	(when (instance? loc gnu.mapping.NamedLocation)
+	  (let* ((loc :: gnu.mapping.NamedLocation loc)
+		 (name loc:KeySymbol:Name))
+	    (when (name:contains pattern)
+	      (format #t "~a\t: ~a\n" name loc))))))))
Index: gnu/kawa/slib/Makefile.am
===================================================================
--- gnu/kawa/slib/Makefile.am	(revision 6296)
+++ gnu/kawa/slib/Makefile.am	(working copy)
@@ -19,7 +19,7 @@
   conditions.scm srfi34.scm \
   srfi37.scm srfi69.scm pregexp.scm \
   genwrite.scm pp.scm ppfile.scm printf.scm \
-  cut.scm testing.scm $(XML_SCM) gui.scm $(SWING_SCM)
+  cut.scm testing.scm repl_commands.scm $(XML_SCM) gui.scm $(SWING_SCM)
 EXTRA_DIST = $(java_SCM) XML.scm swing.scm
 
 all: Makefile scm-classes.stamp $(@GCJ_COMPILED_SELECTED@)
Index: build.xml
===================================================================
--- build.xml	(revision 6296)
+++ build.xml	(working copy)
@@ -468,6 +468,7 @@
         <include name="gui.scm"/>
         <include name="XML.scm"/>
         <include name="swing.scm"/>
+        <include name="repl_commands.scm"/>
       </fileset>
 
   <target name="check-slib-scm-classes">
Index: doc/kawa.texi
===================================================================
--- doc/kawa.texi	(revision 6296)
+++ doc/kawa.texi	(working copy)
@@ -4237,6 +4237,96 @@
 Turn off tracing (debugging output) of @var{procedure}.
 @end deffn
 
+@subsection REPL commands
+
+Some commands to inspect the system are provided by the repl_commands
+module.  You can load it with:
+@example
+(require gnu.kawa.slib.repl_commands)
+@end example
+If you like you can add that line to your @code{.kawarc.scm}.
+
+@deffn Syntax time form
+Evaluate @var{form} and print various timing data to the current
+output port.  Return the values returned by @var{form}.  This macro
+can be used for simple profiling. A typical use looks like this:
+
+@example
+#|kawa:18|# (require gnu.kawa.slib.repl_commands)
+#|kawa:19|# (time (do ((i 0 (+ i 1))) ((= i 1000000) i)))
+; JIT compilation: 1 ms (273 ms total)
+; GC Copy: 13 ms (44 collections)
+; GC MarkSweepCompact: 0 ms (0 collections)
+; Heap: -315,368 (1,219,616)
+; Non-Heap: +1,792 (18,914,928)
+; Elapsed time: 299 ms
+1000000
+#|kawa:20|# 
+@end example
+
+We can see that the evaluation took 299 milliseconds, 13 msec of this
+time were spend in the garbage collector and the GC was triggered 44
+times.  Apparently, Kawa produces a lot of garbage while counting to
+one million.
+@end deffn
+
+@defun apropos pattern &key env
+Search the environment @var{env} for bindings whose name contain the
+substring @var{pattern}.  If @var{env} isn't specified use the
+@code{interaction-environment}.  The matching bindings are printed to
+the current output port.  For example
+
+@example
+#|kawa:34|# (apropos "invoke")
+invoke-static   : gnu.mapping.PlainLocation[invoke-static]
+invoke  : gnu.mapping.PlainLocation[invoke]
+invoke-special  : gnu.mapping.PlainLocation[invoke-special]
+#|kawa:35|#
+@end example
+
+To list all bindings you can use the empty string as argument:
+@code{(apropos "")}.
+@end defun 
+
+@defun room
+Print information about the state of internal storage and its
+management.  @code{room} uses the java.lang.MemoryMXBean internally
+so the exact output depends on the JVM implementation.  
+
+@example
+#|kawa:37|# (room)
+; Memory Pools
+; Code Cache     :  1,044,288
+; Eden Space     :     38,016
+; Survivor Space :     11,480
+; Tenured Gen    :  1,077,968
+; Perm Gen       :  3,148,352
+; Perm Gen [shared-ro]           :  7,513,952
+; Perm Gen [shared-rw]           :  7,506,352
+;
+; Heap           :  1,127,464 (max 532,742,144) 
+; Non-Heap       : 19,212,632 (max 121,634,816)
+#|kawa:38|# 
+@end example
+@end defun
+
+@defun gc &key verbose
+Initiate a full garbage collection.  If the keyword argument VERBOSE
+is true (the default), print various GC statistics.  The output looks
+like this:
+
+@example
+#|kawa:42|# (gc verbose: #t)
+[Full GC[Unloading class atInteractiveLevel$39]
+[Unloading class atInteractiveLevel$40]
+[Unloading class atInteractiveLevel$38]
+[Unloading class atInteractiveLevel$37]
+ 977K->860K(5056K), 0.0416070 secs]
+; heap: -119,920 (881,480) non-heap: +0 (19,228,488)
+#|kawa:43|# 
+@end example
+@end defun
+
 @node Threads, Processes, Debugging, Extensions
 @section Threads
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]