1. Removal of very recently introduced hideFromContextListeners: it was a wrong solution to the problem of running scripts under independent Context instances on the same thread.

2. Optimization of Context.enter()/Context.exit() when ThreadLocal is available:
Store Context[1], not Context in the variable so  Context.enter()/Context.exit() would need to access ThreadVar only once and then update the reference.
This commit is contained in:
igor%mir2.org 2003-11-07 22:24:53 +00:00
Родитель 5b675f523e
Коммит 6006898229
1 изменённых файлов: 92 добавлений и 62 удалений

Просмотреть файл

@ -151,7 +151,14 @@ public class Context
*/ */
public static Context enter(Context cx) public static Context enter(Context cx)
{ {
Context old = getCurrentContext(); Context[] storage = getThreadContextStorage();
Context old;
if (storage != null) {
old = storage[0];
} else {
old = getCurrentContext_jdk11();
}
if (old != null) { if (old != null) {
if (cx != null && cx != old && cx.enterCount != 0) { if (cx != null && cx != old && cx.enterCount != 0) {
// The suplied context must be the context for // The suplied context must be the context for
@ -165,30 +172,20 @@ public class Context
cx = new Context(); cx = new Context();
if (cx.enterCount != 0) Kit.codeBug(); if (cx.enterCount != 0) Kit.codeBug();
if (!cx.hideFromContextListeners && !cx.creationEventWasSent) { if (!cx.creationEventWasSent) {
cx.creationEventWasSent = true; cx.creationEventWasSent = true;
Object listeners = contextListeners; cx.runListeners(CONTEXT_CREATED_EVENT);
for (int i = 0; ; ++i) {
Object l = Kit.getListener(listeners, i);
if (l == null)
break;
((ContextListener)l).contextCreated(cx);
}
} }
} }
if (!cx.hideFromContextListeners) { cx.runListeners(CONTEXT_ENTER_EVENT);
Object listeners = contextListeners;
for (int i = 0; ; ++i) {
Object l = Kit.getListener(listeners, i);
if (l == null)
break;
((ContextListener)l).contextEntered(cx);
}
}
if (old == null) { if (old == null) {
setThreadContext(cx); if (storage != null) {
storage[0] = cx;
} else {
setThreadContext_jdk11(cx);
}
} }
++cx.enterCount; ++cx.enterCount;
@ -210,7 +207,13 @@ public class Context
*/ */
public static void exit() public static void exit()
{ {
Context cx = getCurrentContext(); Context[] storage = getThreadContextStorage();
Context cx;
if (storage != null) {
cx = storage[0];
} else {
cx = getCurrentContext_jdk11();
}
if (cx == null) { if (cx == null) {
throw new IllegalStateException( throw new IllegalStateException(
"Calling Context.exit without previous Context.enter"); "Calling Context.exit without previous Context.enter");
@ -218,25 +221,16 @@ public class Context
if (Context.check && cx.enterCount < 1) Kit.codeBug(); if (Context.check && cx.enterCount < 1) Kit.codeBug();
--cx.enterCount; --cx.enterCount;
if (cx.enterCount == 0) { if (cx.enterCount == 0) {
setThreadContext(null); if (storage != null) {
storage[0] = null;
} else {
setThreadContext_jdk11(null);
}
} }
if (!cx.hideFromContextListeners) { cx.runListeners(CONTEXT_EXIT_EVENT);
Object listeners = contextListeners; if (cx.enterCount == 0) {
for (int i = 0; ; ++i) { cx.runListeners(CONTEXT_RELEASED_EVENT);
Object l = Kit.getListener(listeners, i);
if (l == null)
break;
((ContextListener)l).contextExited(cx);
}
if (cx.enterCount == 0) {
for (int i = 0; ; ++i) {
Object l = Kit.getListener(listeners, i);
if (l == null)
break;
((ContextListener)l).contextReleased(cx);
}
}
} }
} }
@ -261,16 +255,36 @@ public class Context
} }
} }
/** private static final int CONTEXT_CREATED_EVENT = 1;
* Do not notify any listener registered with private static final int CONTEXT_ENTER_EVENT = 2;
* {@link #addContextListener(ContextListener)} about this Context instance. private static final int CONTEXT_EXIT_EVENT = 3;
* The function can only be called if this Context is not associated with private static final int CONTEXT_RELEASED_EVENT = 4;
* any thread.
*/ private void runListeners(int reason)
public final void hideFromContextListeners()
{ {
if (enterCount != 0) throw new IllegalStateException(); Object listeners = contextListeners;
hideFromContextListeners = true; for (int i = 0; ; ++i) {
ContextListener l;
l = (ContextListener)Kit.getListener(listeners, i);
if (l == null)
break;
switch (reason) {
case CONTEXT_CREATED_EVENT:
l.contextCreated(this);
break;
case CONTEXT_ENTER_EVENT:
l.contextEntered(this);
break;
case CONTEXT_EXIT_EVENT:
l.contextExited(this);
break;
case CONTEXT_RELEASED_EVENT:
l.contextReleased(this);
break;
default:
Kit.codeBug();
}
}
} }
/** /**
@ -285,23 +299,40 @@ public class Context
* @see org.mozilla.javascript.Context#enter * @see org.mozilla.javascript.Context#enter
* @see org.mozilla.javascript.Context#exit * @see org.mozilla.javascript.Context#exit
*/ */
public static Context getCurrentContext() { public static Context getCurrentContext()
{
Context[] storage = getThreadContextStorage();
if (storage != null) {
return storage[0];
}
return getCurrentContext_jdk11();
}
private static Context[] getThreadContextStorage()
{
if (threadLocalCx != null) { if (threadLocalCx != null) {
try { try {
return (Context)threadLocalGet.invoke(threadLocalCx, null); Context[] storage
= (Context[])threadLocalGet.invoke(threadLocalCx, null);
if (storage == null) {
storage = new Context[1];
threadLocalSet.invoke(threadLocalCx,
new Object[] { storage });
}
return storage;
} catch (Exception ex) { } } catch (Exception ex) { }
} }
return null;
}
private static Context getCurrentContext_jdk11()
{
Thread t = Thread.currentThread(); Thread t = Thread.currentThread();
return (Context) threadContexts.get(t); return (Context) threadContexts.get(t);
} }
private static void setThreadContext(Context cx) { private static void setThreadContext_jdk11(Context cx)
if (threadLocalCx != null) { {
try {
threadLocalSet.invoke(threadLocalCx, new Object[] { cx });
return;
} catch (Exception ex) { }
}
Thread t = Thread.currentThread(); Thread t = Thread.currentThread();
if (cx != null) { if (cx != null) {
threadContexts.put(t, cx); threadContexts.put(t, cx);
@ -379,7 +410,7 @@ public class Context
* @param version the version as specified by VERSION_1_0, VERSION_1_1, etc. * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc.
*/ */
public void setLanguageVersion(int version) { public void setLanguageVersion(int version) {
Object listeners = instanceListeners; Object listeners = propertyListeners;
if (listeners != null && version != this.version) { if (listeners != null && version != this.version) {
firePropertyChangeImpl(listeners, languageVersionProperty, firePropertyChangeImpl(listeners, languageVersionProperty,
new Integer(this.version), new Integer(this.version),
@ -428,7 +459,7 @@ public class Context
*/ */
public ErrorReporter setErrorReporter(ErrorReporter reporter) { public ErrorReporter setErrorReporter(ErrorReporter reporter) {
ErrorReporter result = errorReporter; ErrorReporter result = errorReporter;
Object listeners = instanceListeners; Object listeners = propertyListeners;
if (listeners != null && errorReporter != reporter) { if (listeners != null && errorReporter != reporter) {
firePropertyChangeImpl(listeners, errorReporterProperty, firePropertyChangeImpl(listeners, errorReporterProperty,
errorReporter, reporter); errorReporter, reporter);
@ -470,7 +501,7 @@ public class Context
*/ */
public void addPropertyChangeListener(PropertyChangeListener listener) public void addPropertyChangeListener(PropertyChangeListener listener)
{ {
instanceListeners = Kit.addListener(instanceListeners, listener); propertyListeners = Kit.addListener(propertyListeners, listener);
} }
/** /**
@ -482,7 +513,7 @@ public class Context
*/ */
public void removePropertyChangeListener(PropertyChangeListener listener) public void removePropertyChangeListener(PropertyChangeListener listener)
{ {
instanceListeners = Kit.removeListener(instanceListeners, listener); propertyListeners = Kit.removeListener(propertyListeners, listener);
} }
/** /**
@ -498,7 +529,7 @@ public class Context
void firePropertyChange(String property, Object oldValue, void firePropertyChange(String property, Object oldValue,
Object newValue) Object newValue)
{ {
Object listeners = instanceListeners; Object listeners = propertyListeners;
if (listeners != null) { if (listeners != null) {
firePropertyChangeImpl(listeners, property, oldValue, newValue); firePropertyChangeImpl(listeners, property, oldValue, newValue);
} }
@ -2187,10 +2218,9 @@ public class Context
Debugger debugger; Debugger debugger;
private Object debuggerData; private Object debuggerData;
private int enterCount; private int enterCount;
private Object instanceListeners; private Object propertyListeners;
private Hashtable hashtable; private Hashtable hashtable;
private ClassLoader applicationClassLoader; private ClassLoader applicationClassLoader;
private boolean hideFromContextListeners;
private boolean creationEventWasSent; private boolean creationEventWasSent;
/** /**