Skip to content

Commit a147bc6

Browse files
authored
Merge pull request #630 from killme2008/fix/tweak-timeout
feat: check timeout every 3000 checkpoints, reduce the cost
2 parents 63db445 + 3f2ba66 commit a147bc6

8 files changed

Lines changed: 46 additions & 18 deletions

File tree

src/main/java/com/googlecode/aviator/AviatorEvaluatorInstance.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ private Map<String, Object> loadScript0(final String abPath) throws IOException
404404
@SuppressWarnings("unchecked")
405405
private Map<String, Object> executeModule(final Expression exp, final String abPath) {
406406
final Env exports = new Env();
407-
exports.configure(this, exp, -1);
407+
exports.configure(this, exp, -1, null);
408408
final Map<String, Object> module = exp.newEnv("exports", exports, "path", abPath);
409409
Map<String, Object> env = exp.newEnv("__MODULE__", module, "exports", exports);
410410
((BaseExpression) exp).execute(env, false);

src/main/java/com/googlecode/aviator/BaseExpression.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,13 @@ protected Env newEnv(final Map<String, Object> map, final boolean direct,
341341
} else {
342342
env = new Env(map);
343343
}
344-
env.configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout));
344+
env.configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout), null);
345345
return env;
346346
}
347347

348348
protected Env genTopEnv(final Map<String, Object> map, boolean checkExecutionTimeout) {
349349
if (map instanceof Env) {
350-
((Env) map).configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout));
350+
((Env) map).configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout), null);
351351
}
352352
Env env =
353353
newEnv(map, this.instance.getOptionValue(Options.USE_USER_ENV_AS_TOP_ENV_DIRECTLY).bool,

src/main/java/com/googlecode/aviator/code/asm/ASMCodeGenerator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import java.util.Stack;
5757
import java.util.concurrent.atomic.AtomicLong;
5858
import com.googlecode.aviator.AviatorEvaluatorInstance;
59-
import com.googlecode.aviator.BaseExpression;
6059
import com.googlecode.aviator.ClassExpression;
6160
import com.googlecode.aviator.Expression;
6261
import com.googlecode.aviator.Options;
@@ -414,6 +413,7 @@ public void onAndRight(final Token<?> lookhead) {
414413

415414
private void visitRightBranch(final Token<?> lookhead, final int ints,
416415
final OperatorType opType) {
416+
this.checkExecutionTimeout();
417417
if (!OperationRuntime.hasRuntimeContext(this.compileEnv, opType)) {
418418
this.mv.visitInsn(DUP);
419419
loadEnv();
@@ -541,6 +541,7 @@ public void onJoinLeft(final Token<?> lookhead) {
541541
}
542542

543543
private void visitLeftBranch(final Token<?> lookhead, final int ints, final OperatorType opType) {
544+
this.checkExecutionTimeout();
544545
if (!OperationRuntime.hasRuntimeContext(this.compileEnv, opType)) {
545546
visitBoolean();
546547
Label l0 = makeLabel();

src/main/java/com/googlecode/aviator/code/interpreter/InterpretContext.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
import java.util.ArrayDeque;
44
import java.util.List;
5-
import java.util.concurrent.TimeUnit;
65
import com.googlecode.aviator.InterpretExpression;
7-
import com.googlecode.aviator.exception.TimeoutException;
86
import com.googlecode.aviator.lexer.token.Token;
97
import com.googlecode.aviator.parser.VariableMeta;
108
import com.googlecode.aviator.runtime.RuntimeUtils;

src/main/java/com/googlecode/aviator/runtime/RuntimeUtils.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
*/
3232
public final class RuntimeUtils {
3333

34+
private static final int CHECKPOINTS = 3000;
35+
3436
private RuntimeUtils() {
3537

3638
}
@@ -106,13 +108,16 @@ public static Sequence seq(final Object o, final Map<String, Object> env) {
106108

107109
public static void checkExecutionTimedOut(final Map<String, Object> env) {
108110
if (env instanceof Env) {
109-
long startNs = ((Env) env).getStartNs();
111+
Env theEnv = (Env) env;
112+
long startNs = theEnv.getStartNs();
110113
if (startNs > 0) {
111114
long execTimeoutNs = getEvalTimeoutNs(env);
112115
if (execTimeoutNs > 0) {
113-
if (Utils.currentTimeNanos() - startNs > execTimeoutNs) {
114-
throw new TimeoutException("Expression execution timed out, exceeded: "
115-
+ getInstance(env).getOptionValue(Options.EVAL_TIMEOUT_MS).number + " ms");
116+
if (theEnv.incExecCheckpointsAndGet() % CHECKPOINTS == 0) {
117+
if (Utils.currentTimeNanos() - startNs > execTimeoutNs) {
118+
throw new TimeoutException("Expression execution timed out, exceeded: "
119+
+ getInstance(env).getOptionValue(Options.EVAL_TIMEOUT_MS).number + " ms");
120+
}
116121
}
117122
}
118123
}

src/main/java/com/googlecode/aviator/runtime/function/LambdaFunction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,11 @@ protected Map<String, Object> newEnv(final Map<String, Object> parentEnv,
241241
Env env = null;
242242
if (!this.inheritEnv) {
243243
final Env contextEnv = new Env(parentEnv, this.context);
244-
contextEnv.configure(this.context.getInstance(), this.expression, this.context.getStartNs());
244+
contextEnv.configure(this.context.getInstance(), this.expression, this.context.getStartNs(),
245+
this.context.getCheckPoints());
245246
env = new Env(contextEnv);
246-
env.configure(this.context.getInstance(), this.expression, this.context.getStartNs());
247+
env.configure(this.context.getInstance(), this.expression, this.context.getStartNs(),
248+
this.context.getCheckPoints());
247249
} else {
248250
// assert (parentEnv == this.context);
249251
env = (Env) parentEnv;

src/main/java/com/googlecode/aviator/utils/Env.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,15 @@ public class Env implements Map<String, Object>, Serializable {
7575
public static final Map<String, Object> EMPTY_ENV = Collections.emptyMap();
7676

7777
// The execution start timestamp in nanoseconds.
78-
private transient long startNs = -1;
78+
private long startNs = -1;
79+
80+
public static class IntCounter {
81+
transient int n = 0;
82+
}
83+
84+
// The "execution" checkpoint times
85+
private transient IntCounter checkPoints = null;
86+
7987

8088

8189
/**
@@ -103,10 +111,23 @@ public void setmOverrides(final Map<String, Object> mOverrides) {
103111
this.mOverrides = mOverrides;
104112
}
105113

114+
106115
public long getStartNs() {
107116
return startNs;
108117
}
109118

119+
public int incExecCheckpointsAndGet() {
120+
if (this.checkPoints == null) {
121+
checkPoints = new IntCounter();
122+
}
123+
return ++checkPoints.n;
124+
}
125+
126+
127+
public IntCounter getCheckPoints() {
128+
return checkPoints;
129+
}
130+
110131
public List<String> getImportedSymbols() {
111132
return this.importedSymbols;
112133
}
@@ -156,16 +177,17 @@ public void setInstance(final AviatorEvaluatorInstance instance) {
156177
}
157178

158179
// Configure the env.
159-
public void configure(final AviatorEvaluatorInstance instance, final Expression exp,
160-
long startNs) {
180+
public void configure(final AviatorEvaluatorInstance instance, final Expression exp, long startNs,
181+
IntCounter checkPoints) {
161182
this.instance = instance;
162183
this.expression = exp;
163-
setStartNs(startNs);
184+
setStats(startNs, checkPoints);
164185
}
165186

166-
private void setStartNs(long startNs) {
187+
private void setStats(long startNs, IntCounter checkPoints) {
167188
if (this.startNs == -1 && startNs > 0) {
168189
this.startNs = startNs;
190+
this.checkPoints = checkPoints;
169191
}
170192
}
171193

src/test/java/com/googlecode/aviator/SimpleELPerformanceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
public class SimpleELPerformanceTest extends TestCase {
99
public void test_perf() throws Exception {
1010

11-
// AviatorEvaluator.setTrace(true);
11+
// AviatorEvaluator.setOption(Options.EVAL_TIMEOUT_MS, 100);
1212
for (int i = 0; i < 10; ++i) {
1313
perf();
1414
perfVarAccess();

0 commit comments

Comments
 (0)