A memory consistency model (or simply memory model) defines the possible values that a shared-memory read may return in a multithreaded programming language. Choosing a memory model involves an inherent performance-programmability tradeoff. The Java language has adopted a relaxed (or weak) memory model that is designed to admit most traditional compiler optimizations and obviate the need for hardware fences on most shared-memory accesses. The downside, however, is that programmers are exposed to a complex and unintuitive semantics and must carefully declare certain variables as volatile in order to enforce program orderings that are necessary for proper behavior. This paper proposes a simpler and stronger memory model for Java through a conceptually small change: every variable has volatile semantics by default, but the language allows a programmer to tag certain variables, methods, or classes as relaxed and provides the current Java semantics for these portions of code. This volatile-by-default semantics provides sequential consistency (SC) for all programs by default. At the same time, expert programmers retain the freedom to build performance-critical libraries that violate the SC semantics. At the outset, it is unclear if the volatile-by-default semantics is practical for Java, given the cost of memory fences on today's hardware platforms. The core contribution of this paper is to demonstrate, through comprehensive empirical evaluation, that the volatile-by-default semantics is arguably acceptable for a predominant use case for Java today Ð server-side applications running on Intel x86 architectures. We present VBD-HotSpot, a modification to Oracle's widely used HotSpot JVM that implements the volatile-by-default semantics for x86. To our knowledge VBD-HotSpot is the first implementation of SC for Java in the context of a modern JVM. VBD-HotSpot incurs an average overhead versus the baseline HotSpot JVM of 28% for the Da Capo benchmarks, which is significant though perhaps less than commonly assumed. Further, VBD-HotSpot incurs average overheads of 12% and 19% respectively on standard benchmark suites for big-data analytics and machine learning in the widely used Spark framework. CCS Concepts: · Software and its engineering → Concurrent programming languages; Just-in-time compilers; Additional Key Words and Phrases: memory consistency models, volatile by default, sequential consistency, Java virtual machine Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than the author(s) must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from permissions@acm.org.  49:2 Lun Liu, Todd Millstein, and Madanlal Musuvathi A memory consistency model (or simply memory model) defines the possible values that a sharedmemory read may return and thus plays a central role in the semantics of a multithreaded programming language. Choosing a memory model for a language involves an inherent performanceprogrammability tradeoff. Sequential consistency (SC) [Lamport 1979 ] provides an intuitive programming model by ensuring that a program's instructions (appear to) execute in a global total order consistent with the per-thread program order. But achieving SC requires the compiler to disable some common optimizations, and on current hardware platforms it further requires the compiler to restrict hardware optimizations by emitting expensive fence instructions on shared-memory accesses. To avoid this cost, the Java language [Manson et al. 2005] has adopted a relaxed (or weak) memory model that is designed to admit most traditional compiler optimizations and obviate the need for hardware fences on most shared-memory accesses. The downside, however, is that programmers must carefully declare certain variables as volatile in order to enforce the per-thread program orderings that are required for proper behavior. If a programmer does not annotate the necessary variables as volatile, programs are exposed to the relaxed semantics of the Java memory model (JMM), which is complex, unintuitive, and can violate critical program invariants. For example, under the JMM an object can be accessed before its constructor has completed, accesses to longs and doubles are not guaranteed to be atomic, and some programming idioms, such as double-checked locking [Bacon et al. 2017; Schmidt and Harrison 1997] , are not guaranteed to behave correctly. As discussed in Section 3, this possibility is not just theoretical: errors due to the failure to annotate certain variables as volatile, which we term missing-annotation bugs, can be found across a range of widely used Java applications. This performance-by-default approach to memory models is acceptable for and consistent with the design philosophy of languages like C and C++ [Boehm and Adve 2008] . However, we argue that such an approach conflicts with the design philosophy of łsafež languages like Java. Indeed, when it comes to type and memory safety, Java instead employs a safe-by-default and performance-by-choice approach: type and memory safety are provided by default, but there is a library of type-unsafe operations meant for use by expert programmers in performance-critical code [Mastrangelo et al. 2015] . In the same vein, this paper proposes a safe-by-default and performance-by-choice approach to enforcing per-thread program order in Java. This approach involves a conceptually simple change to the memory model: every variable has volatile semantics by default, but the language allows a programmer to tag certain classes, methods, or variables as relaxed and provides the current JMM semantics for these portions of code. This volatile-by-default semantics provides a natural form of sequential consistency for Java by default, at the bytecode level: bytecode instructions (appear to) execute atomically and in program order. This also implies that all Java primitive values, including (64-bit) doubles and longs, are atomic irrespective of the bit-width of the underlying architecture. At the same time, expert programmers retain the freedom to build performance-critical libraries that violate this semantics, and they are responsible for protecting clients from any weak behaviors that can result.
REF have proposed a stronger Java memory model, which by default has sequential consistency semantics.
A volatile-by-default JVM for server applications
PACMPL
Computer Science