Most applications using CLOS can be delivered without difficulty. However, there are a few potential exceptions to this rule. Code dynamically redefining classes and methods, and with certain method combinations, needs some extra work.
However, at delivery level 0 it is unlikely that you will need to do anything.
Set the deliver
keyword :keep-clos to
t
or :full-dynamic-definition
to keep the code needed for dynamic definition in the image.
At delivery level 0 the default value of :keep-clos is :full-dynamic-definition
, so you will not need to do anything special.
The LispWorks CLOS implementation achieves fast method dispatch by producing special functions to perform discrimination and method dispatch. Since the required operation can often only be determined by seeing what arguments a generic function is called with, these functions can often end up being generated and compiled at run time.
If the compiler has been removed in a delivered application, then these special run time-generated functions cannot be compiled on the fly.
There are two ways in which the delivery system deals with this problem.
The first is to have a set of pre-compiled "template" constructors which can construct an appropriate function. LispWorks comes with extensive set of such constructors, which should cover most of cases. The programmer can add her own, as explained below.
The other mechanism is to construct generic closures to do the work. The code that generates the closures can cope with:
progn
, multiple-value-prog1
and call-method
forms.In most cases the effect on method dispatch time of using the generic technique is negligible. Pathological cases might, however, cause a slowdown of 10-20% over compiled special functions. In this case, as well as for cases of user-defined complex method combinations which the generic mechanism cannot cope with, the delivered image must have precompiled "template" constructors, and if they are not already there the user needs to add them, as described next.
Even though it cannot compile the functions at run time, delivery can generate the forms for them. The necessary method combination templates can be found by using the keyword :warn-on-missing-templates
. This defaults to nil
. If this keyword is non-nil, a warning is issued whenever a missing template is detected. The value of this keyword can be either a string or a pathname, in which case it is a file to put the warning in, or t,
in which case the warning goes to *terminal-io*
. The warning takes this form:
;*****
;>>> Add this combination to the template file <<<
(CLOS::PRE-COMPILE-COMBINED-METHODS
((1 COMMON-LISP:NIL) COMMON-LISP:NIL (CLOS::_CALL-METHOD_)))
; *****
You can take this template, place it in an ordinary lisp file, return to LispWorks, and compile it. This compiled file should be loaded into the image before delivery. See Incorporating the templates into the application.
Most missing templates can be found statically, and if :warn-on-missing-templates
has been set, they are output at the time of saving the delivery image. An attempt is made to find all missing templates. However, because method combinations are dependent on the actual arguments to generic functions, it is not always possible to find every missing template. The application must be run to be sure of finding all the missing templates.
Note: Valid combinations may be generated or seen in warnings even if they are never used. Delivery can only tell you what combinations the application could potentially use.
A typical measure is to put all the templates generated into a file. You can add new ones to it as you work through the delivery process. The templates must be compiled and loaded into the application before delivery. To do this:
(CLOS::PRE-COMPILE-COMBINED-METHODS ((1 COMMON-LISP:NIL) COMMON-LISP:NIL
(COMMON-LISP:MULTIPLE-VALUE-PROG1 (CLOS::_CALL-METHOD_)
(CLOS::_CALL-METHOD_)
(CLOS::_CALL-METHOD_))))
(CLOS::DEFINE-PRE-TEMPLATES
CLOS::DEMAND-CACHING-DCODE-MISS-FUNCTION (5 COMMON-LISP:NIL (4)))
(CLOS::DEFINE-PRE-TEMPLATES
CLOS::DEMAND-CACHING-DCODE-MISS-FUNCTION (6 COMMON-LISP:NIL (4)))
...
No matter how many times the template form is printed, it only needs to be included in the template file once.
MOP programmers should note that, by default, the direct slots and direct methods of all classes are emptied at delivery level 1 and above. To prevent this, set the deliver
keyword :keep-clos to
t,
:full-dynamic-definition
or :meta-object-slots
as required.
To reduce the size of the delivered image, the delivery process compresses the representation of CLOS metaobjects (classes, generic functions and methods). This includes:
:metaclasses-to-keep-effective-slots
and :classes-to-keep-effective-slots
.keep-clos
. If :keep-clos
is t
, the representation of method objects is not compressed. There is also no compression if you add a method to method-qualifiers
, method-specializers
or method-function
.:keep-clos
is t
, or if you add methods to any of the accessors of generic functions.See Shaking the image for a discussion of how unused class definitions and methods are treated by delivery process.
By default make-instance
checks for valid initargs in LispWorks, signalling an error on an invalid call. However, in a delivered application this behavior may not be useful.
Initarg checking in the delivered application is controlled by the deliver
keyword :make-instance-keyword-check.
For more information about make-instance
initarg checking, see the
LispWorks User Guide and Reference Manual
.
LispWorks Delivery User Guide - 10 Aug 2017