[cmucl-ticket] [cmucl] #63: {{{VM::READ-CYCLE-COUNTER}}} destroys live values in ebx and ecx
cmucl
cmucl-devel at common-lisp.net
Wed Sep 26 04:06:57 UTC 2012
#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 , at 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.
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/63>
cmucl <http://common-lisp.net/project/cmucl>
Cmucl is a high-performance, free Common Lisp implementation.
More information about the cmucl-ticket
mailing list