Ignore:
Timestamp:
Oct 14, 2009, 4:08:44 AM (10 years ago)
Author:
rme
Message:

Add an "emulate" restart for a write-to-watched-object condition.

This operates at a very low level: it emulates the machine instruction
that caused the write.

In order to do this, we suspend other threads and suspend the gc so
that we can use the register state in the exception context to
compute an effective address and perform the store.

The code only knows how to emulate storing a GPR to memory; the
restart will not be offered if the faulting instruction is some other
kind of operation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-1/x86-trap-support.lisp

    r13004 r13014  
    445445                                         :instruction insn)
    446446                                        nil frame-ptr)
     447                    #-windows-target
     448                    (emulate ()
     449                      :test (lambda (c)
     450                              (declare (ignore c))
     451                              (x86-can-emulate-instruction insn))
     452                      :report
     453                      "Emulate this instruction, leaving the object watched."
     454                      (flet ((watchedp (object)
     455                               (%map-areas #'(lambda (x)
     456                                               (when (eq object x)
     457                                                 (return-from watchedp t)))
     458                                           area-watched area-watched)))
     459                        (let ((result nil))
     460                          (with-other-threads-suspended
     461                            (when (watchedp object)
     462                              ;; We now trust that the object is in a
     463                              ;; static gc area.
     464                              (let* ((a (+ (%address-of object) offset))
     465                                     (ptr (%int-to-ptr
     466                                           (logandc2 a (1- *host-page-size*)))))
     467                                (#_mprotect ptr *host-page-size* #$PROT_WRITE)
     468                                (setq result (x86-emulate-instruction xp insn))
     469                                (#_mprotect ptr *host-page-size*
     470                                            (logior #$PROT_READ #$PROT_EXEC)))))
     471                          (if result
     472                            (setq skip insn-length)
     473                            (error "could not emulate the instrution")))))
    447474                    (skip ()
    448475                      :test (lambda (c)
Note: See TracChangeset for help on using the changeset viewer.