diff options
author | aclement <aclement> | 2004-10-11 18:39:06 +0000 |
---|---|---|
committer | aclement <aclement> | 2004-10-11 18:39:06 +0000 |
commit | 5c996fc559581581e9dde60a6f555aa3ff7cc042 (patch) | |
tree | d3f307672d856355aa3b0d8fbf5b81fb9c18f451 /runtime | |
parent | 7fe9492cbb9b857e45531f6c74fbd15f8c551b25 (diff) | |
download | aspectj-5c996fc559581581e9dde60a6f555aa3ff7cc042.tar.gz aspectj-5c996fc559581581e9dde60a6f555aa3ff7cc042.zip |
76030 - cflow optimizations. Part 1 fix - use counters rather than stacks when we can.
Diffstat (limited to 'runtime')
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(); + } } |