Our ClearView system uses this technique to automatically patch otherwise fatal errors in compiled binaries with no access to source code or debugging information. It observes normal, error-free executions of the program to derive a model (in the form of invariants observed to be true in all observed executions) of the normal behavior of the program. It responds to errors that cause the program to crash by finding observed invariants that are violated when the program crashes, developing patches that change the state of the system (typically by changing the values in memory locations or registers) to enforce violated invariants, then observing executions of the system to find patches that successfully eliminate the effect of the error to enable the program to continue to execute. This technique can be especially effective in the context of a community of machines running similar software, since it can enable ClearView to obtain patches that make all machines invulnerable to an attack even though only a few have actually observed the attack.
See our SOSP 2009 paper on this topic for more information on ClearView. An earlier system automatically inferred and enforced data structure consistency constraints to successfully correct errors that violate data structure consistency properties and continue on to provide successful service to users. See our ISSTA 2006 paper on this topic for more information.
One of the most significant results of the Hob project was that its specification techniques enable the verification of externally relevant design properties. The specification for our Hob implementation of the Minesweeper game, for example, expresses the rules of the game in a way that is directly relevant to users of the game. These specifications stand in stark contrast to standard software specifications, which are largely incomprehensible to users of the system since they focus on the internal implementation details of the program rather than properties that are directly relevant to users.
Patrick Lam's PhD thesis presents a comprehensive overview of the Hob system. Our AOSD 2005 paper shows how we use aspect-oriented techniques to enable the modular specification and verification of programs that manipulate sophisticated linked data structures. Our Hob IEEE Transactions on Software Engineering paper focuses on how Hob enables multiple modular pluggable program analyses to work together to prove sophisticated correctness properties. See my publications page for more Hob publications.
Viktor Kuncak's PhD thesis describes the techniques that form the foundation of the Jahob system. Our PLDI 2008 paper describes how we used Jahob to perform the first verification of full functional correctness for a range of linked data structures, including mutable lists, trees, graphs, and hash tables. Our PLDI 2009 paper presents our integrated proof language, which enables developers to guide the correctness proofs while staying within the conceptual framework of the underlying imperative programming language. In this approach, the developer simply controls key proof choice points, with the powerful Jahob integrated reasoning system performing the vast majority of the verification. See my publications page for more Jahob publications, including a broad range of publications on the logical techniques behind Jahob.
I have also prepared an invited paper and an invited talk for SAS 2001 on the analysis of multithreaded programs.
We have developed the following analyses and optimizations:
We used this algorithm to solve a range of analysis problems, including static race detection for parallel divide and conquer programs, automatic parallelization of sequential divide and conquer programs, static detection of array bounds violations, and elimination of array bounds checks. See our PLDI 2000 paper on this topic for more details.
Our JPDC 1998 paper presents an algorithm that performs both data and computation lock coarsening for object-based programs. Our POPL 1997 paper presents a set of general transformations that move lock constructs both within and between procedures to coarsen the lock granularity.
Our ICS 1999 paper presents experimental results from an implementation of this technique. The results show that, for our set of benchmark programs, adaptive replication can improve the overall performance by up to a factor of three over versions that use no replication, and can reduce the memory consumption by up to a factor of four over versions that fully replicate updated objects. Furthermore, adaptive replication never significantly harms the performance and never increases the memory usage without a corresponding increase in the performance.
We have recently developed an extended type system for Java; this system guarantees that any well-typed program is free of data races. It enables the programmer to specify the protection mechanism for each object as part of the object's type. The type can specify either the mutual exclusion lock that protects the object from unsynchronized concurrent accesses, or that threads can safely access the object without synchronization because either 1) the object is immutable, 2) the object is accessible to only the current thread and is not shared between threads, or 3) the current thread holds the unique reference to the object. The type checker uses the type declarations to verify that the program uses each object only in accordance with its declared protection mechanisms.
The result is that programmers can aggressively remove superfluous synchronization without introducing data races. See our OOPSLA 2001 paper on this topic for more details.
We have developed a new analysis approach, commutativity analysis , that exploits the structure of the object-oriented paradigm to view the computation as consisting of operations on objects. It then analyzes the computation at this granularity to determine if operations commute (i.e. generate the same result regardless of the order in which they execute). If all of the operations in a given computation commute, the compiler can automatically generate parallel code. We have used this technique to successfully parallelize a variety of complete application programs, with the automatically parallelized versions running between 14 and 19 times faster (on a 24 processor machine) than the original sequential versions. See our TOPLAS 1997 paper on this topic for more details.
In collaboration with Daniel Jackson, I am investigating ways to check that a program correctly implements high-level design properties expressed using object models. My contribution focuses on new, very precise, program analyses that leverage the design information to focus the analysis on properties of interest to the programmer. The National Science Foundation is currently supporting this research through an ITR grant.
Finally, I have a range of Java analysis and optimization projects underway. These include the exploration of techniques for implementing Real-Time Java, space optimizations for Java programs, techniques that leverage program analysis information to provide very fast atomic transactions, and a range of memory system optimizations such as region-based allocation, elimination of write barriers, and (leveraging program analysis information about object lifetimes) explicit alloc/free optimizations.