3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 11:25:51 +00:00

Java bindings with no finalizers

Replacing finalizers with PhantomReferences, required quite a lot of
changes to the codebase.
This commit is contained in:
George Karpenkov 2016-06-12 14:18:13 +02:00
parent dfc80d3b69
commit 495ef0f055
48 changed files with 368 additions and 939 deletions

View file

@ -17,34 +17,35 @@ Notes:
package com.microsoft.z3;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import static com.microsoft.z3.Constructor.of;
import com.microsoft.z3.enumerations.Z3_ast_print_mode;
import java.util.Map;
/**
* The main interaction with Z3 happens via the Context.
**/
public class Context extends IDisposable
{
/**
* Constructor.
**/
public Context()
{
super();
synchronized (creation_lock) {
public class Context implements AutoCloseable {
private final long m_ctx;
static final Object creation_lock = new Object();
public static Context mkContext() {
long m_ctx;
synchronized (creation_lock) {
m_ctx = Native.mkContextRc(0);
initContext();
// TODO: then adding settings will not be under the lock.
}
return new Context(m_ctx);
}
/**
* Constructor.
* Remarks:
* The following parameters can be set:
* The following parameters can be set:
* - proof (Boolean) Enable proof generation
* - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
* - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
* - trace (Boolean) Tracing support for VCC
* - trace_file_name (String) Trace out file for VCC traces
* - timeout (unsigned) default timeout (in milliseconds) used for solvers
@ -53,20 +54,32 @@ public class Context extends IDisposable
* - model model generation for solvers, this parameter can be overwritten when creating a solver
* - model_validate validate models produced by solvers
* - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver
* Note that in previous versions of Z3, this constructor was also used to set global and
* Note that in previous versions of Z3, this constructor was also used to set global and
* module parameters. For this purpose we should now use {@code Global.setParameter}
**/
public Context(Map<String, String> settings)
public static Context mkContext(Map<String, String> settings)
{
super();
synchronized (creation_lock) {
long m_ctx;
synchronized (creation_lock) {
long cfg = Native.mkConfig();
for (Map.Entry<String, String> kv : settings.entrySet())
Native.setParamValue(cfg, kv.getKey(), kv.getValue());
m_ctx = Native.mkContextRc(cfg);
Native.delConfig(cfg);
initContext();
}
return new Context(m_ctx);
}
/**
* Constructor.
**/
protected Context(long m_ctx)
{
this.m_ctx = m_ctx;
// Code which used to be in "initContext".
setPrintMode(Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT);
Native.setInternalErrorHandler(m_ctx);
}
/**
@ -242,7 +255,7 @@ public class Context extends IDisposable
checkContextMatch(name);
checkContextMatch(fieldNames);
checkContextMatch(fieldSorts);
return new TupleSort(this, name, (int) fieldNames.length, fieldNames,
return new TupleSort(this, name, fieldNames.length, fieldNames,
fieldSorts);
}
@ -319,8 +332,7 @@ public class Context extends IDisposable
Symbol[] fieldNames, Sort[] sorts, int[] sortRefs)
{
return new Constructor(this, name, recognizer, fieldNames, sorts,
return of(this, name, recognizer, fieldNames, sorts,
sortRefs);
}
@ -329,10 +341,8 @@ public class Context extends IDisposable
**/
public Constructor mkConstructor(String name, String recognizer,
String[] fieldNames, Sort[] sorts, int[] sortRefs)
{
return new Constructor(this, mkSymbol(name), mkSymbol(recognizer),
return of(this, mkSymbol(name), mkSymbol(recognizer),
mkSymbols(fieldNames), sorts, sortRefs);
}
@ -525,7 +535,7 @@ public class Context extends IDisposable
throw new Z3Exception("Cannot create a pattern from zero terms");
long[] termsNative = AST.arrayToNative(terms);
return new Pattern(this, Native.mkPattern(nCtx(), (int) terms.length,
return new Pattern(this, Native.mkPattern(nCtx(), terms.length,
termsNative));
}
@ -688,7 +698,7 @@ public class Context extends IDisposable
public BoolExpr mkDistinct(Expr... args)
{
checkContextMatch(args);
return new BoolExpr(this, Native.mkDistinct(nCtx(), (int) args.length,
return new BoolExpr(this, Native.mkDistinct(nCtx(), args.length,
AST.arrayToNative(args)));
}
@ -756,7 +766,7 @@ public class Context extends IDisposable
public BoolExpr mkAnd(BoolExpr... t)
{
checkContextMatch(t);
return new BoolExpr(this, Native.mkAnd(nCtx(), (int) t.length,
return new BoolExpr(this, Native.mkAnd(nCtx(), t.length,
AST.arrayToNative(t)));
}
@ -766,7 +776,7 @@ public class Context extends IDisposable
public BoolExpr mkOr(BoolExpr... t)
{
checkContextMatch(t);
return new BoolExpr(this, Native.mkOr(nCtx(), (int) t.length,
return new BoolExpr(this, Native.mkOr(nCtx(), t.length,
AST.arrayToNative(t)));
}
@ -777,7 +787,7 @@ public class Context extends IDisposable
{
checkContextMatch(t);
return (ArithExpr) Expr.create(this,
Native.mkAdd(nCtx(), (int) t.length, AST.arrayToNative(t)));
Native.mkAdd(nCtx(), t.length, AST.arrayToNative(t)));
}
/**
@ -787,7 +797,7 @@ public class Context extends IDisposable
{
checkContextMatch(t);
return (ArithExpr) Expr.create(this,
Native.mkMul(nCtx(), (int) t.length, AST.arrayToNative(t)));
Native.mkMul(nCtx(), t.length, AST.arrayToNative(t)));
}
/**
@ -797,7 +807,7 @@ public class Context extends IDisposable
{
checkContextMatch(t);
return (ArithExpr) Expr.create(this,
Native.mkSub(nCtx(), (int) t.length, AST.arrayToNative(t)));
Native.mkSub(nCtx(), t.length, AST.arrayToNative(t)));
}
/**
@ -1814,7 +1824,7 @@ public class Context extends IDisposable
{
checkContextMatch(args);
return (ArrayExpr)Expr.create(this,
Native.mkSetUnion(nCtx(), (int) args.length,
Native.mkSetUnion(nCtx(), args.length,
AST.arrayToNative(args)));
}
@ -1825,7 +1835,7 @@ public class Context extends IDisposable
{
checkContextMatch(args);
return (ArrayExpr)Expr.create(this,
Native.mkSetIntersect(nCtx(), (int) args.length,
Native.mkSetIntersect(nCtx(), args.length,
AST.arrayToNative(args)));
}
@ -1912,7 +1922,7 @@ public class Context extends IDisposable
public SeqExpr MkConcat(SeqExpr... t)
{
checkContextMatch(t);
return new SeqExpr(this, Native.mkSeqConcat(nCtx(), (int)t.length, AST.arrayToNative(t)));
return new SeqExpr(this, Native.mkSeqConcat(nCtx(), t.length, AST.arrayToNative(t)));
}
@ -2040,7 +2050,7 @@ public class Context extends IDisposable
public ReExpr MkConcat(ReExpr... t)
{
checkContextMatch(t);
return new ReExpr(this, Native.mkReConcat(nCtx(), (int)t.length, AST.arrayToNative(t)));
return new ReExpr(this, Native.mkReConcat(nCtx(), t.length, AST.arrayToNative(t)));
}
/**
@ -2049,7 +2059,7 @@ public class Context extends IDisposable
public ReExpr MkUnion(ReExpr... t)
{
checkContextMatch(t);
return new ReExpr(this, Native.mkReUnion(nCtx(), (int)t.length, AST.arrayToNative(t)));
return new ReExpr(this, Native.mkReUnion(nCtx(), t.length, AST.arrayToNative(t)));
}
@ -2258,7 +2268,7 @@ public class Context extends IDisposable
Symbol quantifierID, Symbol skolemID)
{
return new Quantifier(this, true, sorts, names, body, weight, patterns,
return Quantifier.of(this, true, sorts, names, body, weight, patterns,
noPatterns, quantifierID, skolemID);
}
@ -2271,7 +2281,7 @@ public class Context extends IDisposable
Symbol skolemID)
{
return new Quantifier(this, true, boundConstants, body, weight,
return Quantifier.of(this, true, boundConstants, body, weight,
patterns, noPatterns, quantifierID, skolemID);
}
@ -2284,7 +2294,7 @@ public class Context extends IDisposable
Symbol quantifierID, Symbol skolemID)
{
return new Quantifier(this, false, sorts, names, body, weight,
return Quantifier.of(this, false, sorts, names, body, weight,
patterns, noPatterns, quantifierID, skolemID);
}
@ -2297,7 +2307,7 @@ public class Context extends IDisposable
Symbol skolemID)
{
return new Quantifier(this, false, boundConstants, body, weight,
return Quantifier.of(this, false, boundConstants, body, weight,
patterns, noPatterns, quantifierID, skolemID);
}
@ -3814,7 +3824,7 @@ public class Context extends IDisposable
* must be a native object obtained from Z3 (e.g., through
* {@code UnwrapAST}) and that it must have a correct reference count.
* @see Native#incRef
* @see unwrapAST
* @see #unwrapAST
* @param nativeObject The native pointer to wrap.
**/
public AST wrapAST(long nativeObject)
@ -3869,19 +3879,12 @@ public class Context extends IDisposable
Native.updateParamValue(nCtx(), id, value);
}
protected long m_ctx = 0;
protected static final Object creation_lock = new Object();
long nCtx()
{
return m_ctx;
}
void initContext()
{
setPrintMode(Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT);
Native.setInternalErrorHandler(nCtx());
}
void checkContextMatch(Z3Object other)
{
@ -3925,110 +3928,103 @@ public class Context extends IDisposable
private TacticDecRefQueue m_Tactic_DRQ = new TacticDecRefQueue(10);
private FixedpointDecRefQueue m_Fixedpoint_DRQ = new FixedpointDecRefQueue(10);
private OptimizeDecRefQueue m_Optimize_DRQ = new OptimizeDecRefQueue(10);
private ConstructorDecRefQueue m_Constructor_DRQ = new ConstructorDecRefQueue(10);
private ConstructorListDecRefQueue m_ConstructorList_DRQ =
new ConstructorListDecRefQueue(10);
public IDecRefQueue getASTDRQ()
public IDecRefQueue<Constructor> getConstructorDRQ() {
return m_Constructor_DRQ;
}
public IDecRefQueue<ConstructorList> getConstructorListDRQ() {
return m_ConstructorList_DRQ;
}
public IDecRefQueue<AST> getASTDRQ()
{
return m_AST_DRQ;
}
public IDecRefQueue getASTMapDRQ()
public IDecRefQueue<ASTMap> getASTMapDRQ()
{
return m_ASTMap_DRQ;
}
public IDecRefQueue getASTVectorDRQ()
public IDecRefQueue<ASTVector> getASTVectorDRQ()
{
return m_ASTVector_DRQ;
}
public IDecRefQueue getApplyResultDRQ()
public IDecRefQueue<ApplyResult> getApplyResultDRQ()
{
return m_ApplyResult_DRQ;
}
public IDecRefQueue getFuncEntryDRQ()
public IDecRefQueue<FuncInterp.Entry> getFuncEntryDRQ()
{
return m_FuncEntry_DRQ;
}
public IDecRefQueue getFuncInterpDRQ()
public IDecRefQueue<FuncInterp> getFuncInterpDRQ()
{
return m_FuncInterp_DRQ;
}
public IDecRefQueue getGoalDRQ()
public IDecRefQueue<Goal> getGoalDRQ()
{
return m_Goal_DRQ;
}
public IDecRefQueue getModelDRQ()
public IDecRefQueue<Model> getModelDRQ()
{
return m_Model_DRQ;
}
public IDecRefQueue getParamsDRQ()
public IDecRefQueue<Params> getParamsDRQ()
{
return m_Params_DRQ;
}
public IDecRefQueue getParamDescrsDRQ()
public IDecRefQueue<ParamDescrs> getParamDescrsDRQ()
{
return m_ParamDescrs_DRQ;
}
public IDecRefQueue getProbeDRQ()
public IDecRefQueue<Probe> getProbeDRQ()
{
return m_Probe_DRQ;
}
public IDecRefQueue getSolverDRQ()
public IDecRefQueue<Solver> getSolverDRQ()
{
return m_Solver_DRQ;
}
public IDecRefQueue getStatisticsDRQ()
public IDecRefQueue<Statistics> getStatisticsDRQ()
{
return m_Statistics_DRQ;
}
public IDecRefQueue getTacticDRQ()
public IDecRefQueue<Tactic> getTacticDRQ()
{
return m_Tactic_DRQ;
}
public IDecRefQueue getFixedpointDRQ()
public IDecRefQueue<Fixedpoint> getFixedpointDRQ()
{
return m_Fixedpoint_DRQ;
}
public IDecRefQueue getOptimizeDRQ()
public IDecRefQueue<Optimize> getOptimizeDRQ()
{
return m_Optimize_DRQ;
}
protected AtomicInteger m_refCount = new AtomicInteger(0);
/**
* Finalizer.
* @throws Throwable
**/
protected void finalize() throws Throwable
{
try {
dispose();
}
catch (Throwable t) {
throw t;
}
finally {
super.finalize();
}
}
/**
* Disposes of the context.
**/
public void dispose()
@Override
public void close()
{
m_AST_DRQ.clear(this);
m_ASTMap_DRQ.clear(this);
@ -4052,15 +4048,7 @@ public class Context extends IDisposable
m_stringSort = null;
synchronized (creation_lock) {
if (m_refCount.get() == 0 && m_ctx != 0) {
try {
Native.delContext(m_ctx);
} catch (Z3Exception e) {
// OK?
System.out.println("Context deletion failed; memory leak possible.");
}
m_ctx = 0;
}
Native.delContext(m_ctx);
}
}
}