/****************************************************************************** * Copyright (c) 2009 - 2015 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *****************************************************************************/ /** * */ package com.ibm.wala.memsat.concurrent.memory.jmm; import static com.ibm.wala.memsat.frontEnd.InlinedInstruction.Action.NORMAL_READ; import static com.ibm.wala.memsat.frontEnd.InlinedInstruction.Action.SPECIAL; import static com.ibm.wala.memsat.frontEnd.InlinedInstruction.Action.VOLATILE_READ; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import com.ibm.wala.memsat.concurrent.Program; import com.ibm.wala.types.MethodReference; import kodkod.ast.Expression; import kodkod.ast.Formula; import kodkod.ast.Variable; /** * Implements the alternative definition of the JMM, given by * Sevcik and Aspinall. * * @see [1] D.�Aspinall and J.�Sevcik. Formalising Java�s data race free guarantee. In * Theorem Proving in Higher-Order Logics (TPHOLs �07), pages 22�37, 2007. * @see [2] D.�Aspinall and J.�Sevc�k. Java memory model examples: good, bad and ugly. * In VAMP �07, Lisbon, Portugal, September 2007. * @see [3] J.�Sevc�k and D.�Aspinall. On validity of program transformations in the Java memory model. * In ECOOP �08, volume 5142 of LNCS, pages 27�51. Springer Berlin, 2008. * @author etorlak */ public final class JMMAlt extends JavaMemoryModel { /** * Constructs a new instance of JMMAlt that will use the given number of speculations * and that will treat calls to specified methods as external actions. */ public JMMAlt(int maxSpeculations, Set<MethodReference> memoryInstructions) { super(maxSpeculations, memoryInstructions); } /** * Returns the JMMAlt rule for the hb relations: for all reads r in C_i, * W(r) <=_{hb} r iff W(r) <=_{hb_i} r, and not r <=_{hb_i} W(r) * @see com.ibm.wala.memsat.concurrent.memory.jmm.JavaMemoryModel#rule2(com.ibm.wala.memsat.concurrent.Program, com.ibm.wala.memsat.concurrent.memory.jmm.JMMExecution, java.util.List, java.util.List) */ @Override protected Formula rule2(Program prog, JMMExecution main, List<JMMExecution> speculations, List<? extends Expression> commits) { final Collection<Formula> ret = new ArrayList<Formula>(maxSpeculations); final Expression reads = prog.allOf(NORMAL_READ,VOLATILE_READ); final Expression hb = main.hb(); for(int i = 1; i < maxSpeculations; i++) { final Variable r = Variable.unary("r"+i); final Expression w = main.w(r); final Expression C_i = commits.get(i); final Expression hb_i = speculations.get(i).hb(); final Expression W2r = w.product(r); final Formula f1 = W2r.in(hb).iff(W2r.in(hb_i)); final Formula f2 = r.product(w).in(hb_i).not(); ret.add( f1.and(f2).forAll(r.oneOf(C_i.intersection(reads))) ); } return Formula.and(ret); } /** * JMMAlt omits the third rule. This method simply returns TRUE. * @see com.ibm.wala.memsat.concurrent.memory.jmm.JavaMemoryModel#rule3(com.ibm.wala.memsat.concurrent.Program, com.ibm.wala.memsat.concurrent.memory.jmm.JMMExecution, java.util.List, java.util.List) */ @Override protected Formula rule3(Program prog, JMMExecution main, List<JMMExecution> speculations, List<? extends Expression> commits) { return Formula.TRUE; } /** * Returns the JMMAlt rule for the visibility of committed writes: * for all reads r in C_i - C_{i-1}, W(r) in C_{i-1} * @see com.ibm.wala.memsat.concurrent.memory.jmm.JavaMemoryModel#rule7(com.ibm.wala.memsat.concurrent.Program, com.ibm.wala.memsat.concurrent.memory.jmm.JMMExecution, java.util.List, java.util.List) */ @Override protected Formula rule7(Program prog, JMMExecution main, List<JMMExecution> speculations, List<? extends Expression> commits) { final Collection<Formula> ret = new ArrayList<Formula>(maxSpeculations); final Expression reads = prog.allOf(NORMAL_READ,VOLATILE_READ); for(int i = 1; i < maxSpeculations; i++) { final Expression C_i = commits.get(i), C_j = commits.get(i-1); final Variable r = Variable.unary("r" + i); ret.add( main.w(r).in(C_j).forAll(r.oneOf(C_i.difference(C_j).intersection(reads))) ); } return Formula.and(ret); } /** * JMMAlt omits the eight rule [1,3]. This method simply returns TRUE. * @see com.ibm.wala.memsat.concurrent.memory.jmm.JavaMemoryModel#rule8(com.ibm.wala.memsat.concurrent.Program, com.ibm.wala.memsat.concurrent.memory.jmm.JMMExecution, java.util.List, java.util.List) */ @Override protected Formula rule8(Program prog, JMMExecution main, List<JMMExecution> speculations, List<? extends Expression> commits) { return Formula.TRUE; } /** * Returns the JMMAlt rule for external actions [3]: if y in C_i is an external action * and x <=_{hb} y, then x in C_i * @see com.ibm.wala.memsat.concurrent.memory.jmm.JavaMemoryModel#rule9(com.ibm.wala.memsat.concurrent.Program, com.ibm.wala.memsat.concurrent.memory.jmm.JMMExecution, java.util.List, java.util.List) */ @Override protected Formula rule9(Program prog, JMMExecution main, List<JMMExecution> speculations, List<? extends Expression> commits) { final Collection<Formula> ret = new ArrayList<Formula>(maxSpeculations); final Expression externals = prog.allOf(SPECIAL); final Expression hb = main.hb(); for(int i = 1; i < maxSpeculations; i++) { final Expression C_i = commits.get(i); final Variable y = Variable.unary("y"+i); ret.add( hb.join(y).in(C_i).forAll(y.oneOf(C_i.intersection(externals))) ); } return Formula.and(ret); } /** * {@inheritDoc} * @see java.lang.Object#toString() */ public String toString() { return "JMMAlt"; } }