#63: {{{VM::READ-CYCLE-COUNTER}}} destroys live values in ebx and ecx --------------------+------------------------------------------------------- Reporter: rtoy | Owner: somebody Type: defect | Status: new Priority: major | Milestone: Component: Core | Version: 2012-09 Keywords: | --------------------+------------------------------------------------------- Consider the following code: {{{ (eval-when (:compile-toplevel :execute) (defmacro with-cycle-counter (&body body) (let ((hi0 (gensym)) (hi1 (gensym)) (lo0 (gensym)) (lo1 (gensym))) `(multiple-value-bind (,lo0 ,hi0) (vm::read-cycle-counter) (values (locally ,@body) (multiple-value-bind (,lo1 ,hi1) (vm::read-cycle-counter) (+ (ash (- ,hi1 ,hi0) 32) (- ,lo1 ,lo0))))))) )
(defun bar (x) (declare (type (and fixnum unsigned-byte) x) (optimize speed (safety 0))) (with-cycle-counter (let ((sum 0d0)) (declare (double-float sum)) (dotimes (k x) (declare (type (and fixnum unsigned-byte) k)) (incf sum k)) sum))) }}}
When compiled, you get funny results like {{{ * (bar 1000000) 0.0d0 408 }}}
This happens because {{{READ-CYCLE-COUNTER}}} uses the {{{CPUID}}} instruction that writes values to the eax, ebx, ecx, and edx registers, but the VOP for {{{READ-CYCLE-COUNTER}}} doesn't know that ebx and ecx are written. Thus the vop can cause any live values in the ebx and ecx registers to be destroyed, as happens in this example.