close Warning: Can't synchronize with repository "(default)" ("(default)" is not readable or not a Git repository.). Look in the Trac log for more information.

Opened 12 years ago

Closed 12 years ago

#63 closed defect (fixed)

VM::READ-CYCLE-COUNTER destroys live values in ebx and ecx registers

Reported by: Raymond Toy Owned by: somebody
Priority: major Milestone:
Component: Core Version: 2012-09
Keywords: Cc:

Description

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.

Change History (2)

comment:1 Changed 12 years ago by Raymond Toy

Summary: {{{VM::READ-CYCLE-COUNTER}}} destroys live values in ebx and ecxVM::READ-CYCLE-COUNTER destroys live values in ebx and ecx registers

Clean up summary line.

comment:2 Changed 12 years ago by toy.raymond@…

Resolution: fixed
Status: newclosed

commit 3832e020b43c1270e0710097381fb718271e61bf Author: Raymond Toy <toy.raymond@…> Date: Tue Sep 25 21:09:46 2012 -0700

Fix ticket:63.

Note: See TracTickets for help on using tickets.