1. A method for parallel execution of programs, comprising: while executing a program in parallel: creating a first program replica for a first thread, wherein the first program replica comprises a first intermediate representation of at least a portion of the program, and wherein the first intermediate representation comprises: a write operation that writes to a property of a first object that is identified by a first identifier specifying that the first object is either a shared object or a thread local object; performing a first speculation that the first object is a thread-local object; performing a first optimization on the write operation based on the first speculation, wherein performing the first optimization comprises modifying the first intermediate representation to include compiled machine code that allows the write operation to directly write to the property of the first object; making a determination, using the first identifier, that the first object is either a shared object or a thread-local object; when the first object is a thread-local object, performing the write operation by writing directly to the property of first object; and when the first object is a shared object: de-optimizing the write operation, based on the determination, by undoing the first optimization to obtain a de-optimized write operation; adding instrumentation to the first intermediate representation to implement a software transactional memory (STM) system for the de-optimized write operation, wherein adding instrumentation to the intermediate representation comprises creating a lazy clone of the first object, the lazy clone having initially no properties; performing the de-optimized write operation by copying the property of the first object to the lazy clone, and writing to the property of the lazy clone to obtain a modified lazy clone; and committing the property of the modified lazy clone by copying the property of the modified lazy clone to the property of the first object.