aboutsummaryrefslogtreecommitdiffstats
path: root/runtime/src
diff options
context:
space:
mode:
authoraclement <aclement>2004-10-11 18:39:06 +0000
committeraclement <aclement>2004-10-11 18:39:06 +0000
commit5c996fc559581581e9dde60a6f555aa3ff7cc042 (patch)
treed3f307672d856355aa3b0d8fbf5b81fb9c18f451 /runtime/src
parent7fe9492cbb9b857e45531f6c74fbd15f8c551b25 (diff)
downloadaspectj-5c996fc559581581e9dde60a6f555aa3ff7cc042.tar.gz
aspectj-5c996fc559581581e9dde60a6f555aa3ff7cc042.zip
76030 - cflow optimizations. Part 1 fix - use counters rather than stacks when we can.
Diffstat (limited to 'runtime/src')
-rw-r--r--runtime/src/org/aspectj/runtime/internal/CFlowCounter.java75
-rw-r--r--runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounter.java21
-rw-r--r--runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounterImpl11.java74
-rw-r--r--runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactory.java1
-rw-r--r--runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl.java22
-rw-r--r--runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl11.java4
6 files changed, 197 insertions, 0 deletions
diff --git a/runtime/src/org/aspectj/runtime/internal/CFlowCounter.java b/runtime/src/org/aspectj/runtime/internal/CFlowCounter.java
new file mode 100644
index 000000000..e48f67864
--- /dev/null
+++ b/runtime/src/org/aspectj/runtime/internal/CFlowCounter.java
@@ -0,0 +1,75 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.runtime.internal;
+
+import org.aspectj.runtime.internal.cflowstack.ThreadCounter;
+import org.aspectj.runtime.internal.cflowstack.ThreadStackFactory;
+import org.aspectj.runtime.internal.cflowstack.ThreadStackFactoryImpl;
+import org.aspectj.runtime.internal.cflowstack.ThreadStackFactoryImpl11;
+
+
+public class CFlowCounter {
+
+ private static ThreadStackFactory tsFactory;
+ private ThreadCounter flowHeightHandler;
+
+ static {
+ selectFactoryForVMVersion();
+ }
+
+ public CFlowCounter() {
+ flowHeightHandler = tsFactory.getNewThreadCounter();
+ }
+
+ public void inc() {
+ flowHeightHandler.inc();
+ }
+
+ public void dec() {
+ flowHeightHandler.dec();
+ }
+
+ public boolean isValid() {
+ return flowHeightHandler.isNotZero();
+ }
+
+
+ private static ThreadStackFactory getThreadLocalStackFactory() { return new ThreadStackFactoryImpl(); }
+ private static ThreadStackFactory getThreadLocalStackFactoryFor11() { return new ThreadStackFactoryImpl11(); }
+
+ private static void selectFactoryForVMVersion() {
+ String override = System.getProperty("aspectj.runtime.cflowstack.usethreadlocal","unspecified");
+ boolean useThreadLocalImplementation = false;
+ if (override.equals("unspecified")) {
+ String v = System.getProperty("java.class.version","0.0");
+ // Java 1.2 is version 46.0 and above
+ useThreadLocalImplementation = (v.compareTo("46.0") >= 0);
+ } else {
+ useThreadLocalImplementation = override.equals("yes") || override.equals("true");
+ }
+ // System.err.println("Trying to use thread local implementation? "+useThreadLocalImplementation);
+ if (useThreadLocalImplementation) {
+ tsFactory = getThreadLocalStackFactory();
+ } else {
+ tsFactory = getThreadLocalStackFactoryFor11();
+ }
+ }
+
+ // For debug ...
+ public static String getThreadStackFactoryClassName() {
+ return tsFactory.getClass().getName();
+ }
+
+}
diff --git a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounter.java b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounter.java
new file mode 100644
index 000000000..96f136ec3
--- /dev/null
+++ b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounter.java
@@ -0,0 +1,21 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+
+package org.aspectj.runtime.internal.cflowstack;
+
+
+public interface ThreadCounter {
+ public void inc();
+ public void dec();
+ public boolean isNotZero();
+} \ No newline at end of file
diff --git a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounterImpl11.java b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounterImpl11.java
new file mode 100644
index 000000000..997f5fed3
--- /dev/null
+++ b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadCounterImpl11.java
@@ -0,0 +1,74 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * Copied from bits of original CFlowStack
+ * ******************************************************************/
+package org.aspectj.runtime.internal.cflowstack;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+public class ThreadCounterImpl11 implements ThreadCounter {
+ private Hashtable counters = new Hashtable();
+ private Thread cached_thread;
+ private Counter cached_counter;
+
+ private int change_count = 0;
+ private static final int COLLECT_AT = 20000;
+ private static final int MIN_COLLECT_AT = 100;
+
+ static class Counter {
+ protected int value = 0;
+ }
+
+ private synchronized Counter getThreadCounter() {
+ if (Thread.currentThread() != cached_thread) {
+ cached_thread = Thread.currentThread();
+ cached_counter = (Counter)counters.get(cached_thread);
+ if (cached_counter == null) {
+ cached_counter = new Counter();
+ counters.put(cached_thread, cached_counter);
+ }
+ change_count++;
+ // Collect more often if there are many threads, but not *too* often
+ int size = Math.max(1, counters.size()); // should be >1 b/c always live threads, but...
+ if (change_count > Math.max(MIN_COLLECT_AT, COLLECT_AT/size)) {
+ List dead_stacks = new ArrayList();
+ for (Enumeration e = counters.keys(); e.hasMoreElements(); ) {
+ Thread t = (Thread)e.nextElement();
+ if (!t.isAlive()) dead_stacks.add(t);
+ }
+ for (Iterator e = dead_stacks.iterator(); e.hasNext(); ) {
+ Thread t = (Thread)e.next();
+ counters.remove(t);
+ }
+ change_count = 0;
+ }
+ }
+ return cached_counter;
+ }
+
+ public void inc() {
+ getThreadCounter().value++;
+ }
+
+ public void dec() {
+ getThreadCounter().value--;
+ }
+
+ public boolean isNotZero() {
+ return getThreadCounter().value!=0;
+ }
+
+}
diff --git a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactory.java b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactory.java
index d382acbc8..b79b63a98 100644
--- a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactory.java
+++ b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactory.java
@@ -15,5 +15,6 @@ package org.aspectj.runtime.internal.cflowstack;
public interface ThreadStackFactory {
public ThreadStack getNewThreadStack();
+ public ThreadCounter getNewThreadCounter();
}
diff --git a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl.java b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl.java
index d39b7fcb6..98ca2f4b5 100644
--- a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl.java
+++ b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl.java
@@ -28,5 +28,27 @@ public class ThreadStackFactoryImpl implements ThreadStackFactory {
public ThreadStack getNewThreadStack() {
return new ThreadStackImpl();
}
+
+ private static class ThreadCounterImpl extends ThreadLocal implements ThreadCounter {
+
+ public Object initialValue() {
+ return new Counter();
+ }
+ public Counter getThreadCounter() {
+ return (Counter)get();
+ }
+
+ public void inc() { getThreadCounter().value++; }
+ public void dec() { getThreadCounter().value--; }
+ public boolean isNotZero() { return getThreadCounter().value!= 0; }
+
+ static class Counter {
+ protected int value = 0;
+ }
+ }
+
+ public ThreadCounter getNewThreadCounter() {
+ return new ThreadCounterImpl();
+ }
}
diff --git a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl11.java b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl11.java
index 350a68109..f4d2a2230 100644
--- a/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl11.java
+++ b/runtime/src/org/aspectj/runtime/internal/cflowstack/ThreadStackFactoryImpl11.java
@@ -18,5 +18,9 @@ public class ThreadStackFactoryImpl11 implements ThreadStackFactory {
public ThreadStack getNewThreadStack() {
return new ThreadStackImpl11();
}
+
+ public ThreadCounter getNewThreadCounter() {
+ return new ThreadCounterImpl11();
+ }
}