Bug 757375: concurrency fixes to work with monocle (p=jasowill,r=dtomack)
authorDan Schaffer <Dan.Schaffer@adobe.com>
Thu, 25 Oct 2012 07:57:17 -0700
changeset 7573 bf1fa4452689
parent 7572 24549a74fde9
child 7574 19ecae71ae5a
push id4262
push userdschaffe@adobe.com
push dateWed, 30 Jan 2013 19:01:31 +0000
reviewersdtomack
bugs757375, 1128847, 1129007
Bug 757375: concurrency fixes to work with monocle (p=jasowill,r=dtomack) integrate 1128847 CL@1129007
VMPI/ThreadsWin.cpp
core/AvmCore.cpp
core/AvmCore.h
core/ConcurrencyGlue.cpp
core/ConcurrencyGlue.h
core/Isolate-inlines.h
core/Isolate.cpp
core/Isolate.h
core/Toplevel-inlines.h
core/Toplevel.cpp
core/Toplevel.h
extensions/ST_workers_Promise.st
extensions/SelftestExec.cpp
extensions/SelftestInit.cpp
generated/avmplus-tracers.hh
generated/builtin.abc
generated/builtin.cpp
generated/shell_toplevel.abc
generated/shell_toplevel.cpp
shell/avmshell.cpp
--- a/VMPI/ThreadsWin.cpp
+++ b/VMPI/ThreadsWin.cpp
@@ -105,33 +105,40 @@ bool VMPI_condVarTimedWaitInternal(vmpi_
 {
 
     // We use the same emulation technique as FP.
     // Although post-notify scheduling is not exactly fair, the algorithm is simple.
     // If we want something fairer then use Alexander Terekhov's 8a algorithm.
 
     // Add the calling thread to the condition variable's list of waiting threads.
     // Note that the linked list is implicitly guarded by the mutex paired with the conditional variable.
+    int32_t timeout = infinite ? INFINITE : timeout_millis;
     WaitingThread thisThread;
     thisThread.threadID = GetCurrentThreadId();
-    thisThread.notified = false;
+    thisThread.notified = timeout == 0;
     thisThread.next = NULL;
-    if (condvar->head == NULL) {
-        condvar->head = &thisThread;
-    } else {
-        condvar->tail->next = &thisThread;
+    if (timeout != 0) {
+        if (condvar->head == NULL) {
+            condvar->head = &thisThread;
+        } else {
+            condvar->tail->next = &thisThread;
+        }
+        condvar->tail = &thisThread;
     }
-    condvar->tail = &thisThread;
-
     // Unlock the mutex and then sleep until we are notified or timeout.
     // Note that there should be *no* lost wakeups between the unlock and the sleep, as all notifies are
     // queued as APCs.
     LeaveCriticalSection(mutex);
-    const DWORD rtn = SleepEx(infinite ? INFINITE : timeout_millis, true);
-
+    DWORD rtn = 0;
+    if (timeout == 0) {
+        SwitchToThread();
+    }
+    else  {
+        rtn = SleepEx(timeout, true);
+    }
     // As per pthread condition variable semantics, we block until we can re-acquire the mutex we released.
     EnterCriticalSection(mutex);
 
     if (!thisThread.notified) {
         // A spurious or time-out wake-up, so the thread must remove itself from the condvar's wait list.
         WaitingThread* waiter = condvar->head;
         WaitingThread* prev = NULL;
         do {
--- a/core/AvmCore.cpp
+++ b/core/AvmCore.cpp
@@ -538,23 +538,24 @@ namespace avmplus
             // call String::createLatin1() with an explicit length of 1; required
             // when singleChar==0, because in that case we need a string
             // which is a single character with value 0
             cachedChars[i] = internString(String::createLatin1(this, &k_cachedChars[i], 1));
         }
 
         workerStates[0] = internConstantStringLatin1("none");
         workerStates[1] = internConstantStringLatin1("new");
-        workerStates[2] = internConstantStringLatin1("starting");
-        workerStates[3] = internConstantStringLatin1("running");
-        workerStates[4] = internConstantStringLatin1("finishing");
-        workerStates[5] = internConstantStringLatin1("terminated");
-        workerStates[6] = internConstantStringLatin1("failed");
-        workerStates[7] = internConstantStringLatin1("aborted");
-        workerStates[8] = internConstantStringLatin1("exception");
+        workerStates[2] = internConstantStringLatin1("canstart");
+        workerStates[3] = internConstantStringLatin1("starting");
+        workerStates[4] = internConstantStringLatin1("running");
+        workerStates[5] = internConstantStringLatin1("finishing");
+        workerStates[6] = internConstantStringLatin1("terminated");
+        workerStates[7] = internConstantStringLatin1("failed");
+        workerStates[8] = internConstantStringLatin1("aborted");
+        workerStates[9] = internConstantStringLatin1("exception");
 
 
         booleanStrings[0] = kfalse;
         booleanStrings[1] = ktrue;
 
         // init kEmptyString last, so that StringObject can use it as a sentinel for
         // determining if all the cached strings are valid.
         kEmptyString = internConstantStringLatin1("");
@@ -5609,16 +5610,21 @@ 22. Return false.
     /* static */
     void AvmCore::releasePCREContext()
     {
         PCREContext.destroy();
     }
 
 #endif // VMCFG_EPOC_EMULATOR
 
+    void AvmCore::clearInterrupt()
+    {
+        interrupted = NotInterrupted;
+    }
+
     void AvmCore::raiseInterrupt(InterruptReason reason)
     {
         AvmAssert(reason != NotInterrupted);
         AvmAssert(reason != SafepointPoll); // Don't use this for safepoints
 		// If this core is already suppose to be in a safepoint poll state, then pend the reason for
 		// examination after the safepoint.
 		if (interrupted == SafepointPoll) {
 			pending_interrupt = reason;
--- a/core/AvmCore.h
+++ b/core/AvmCore.h
@@ -904,17 +904,17 @@ const int kBufferPadding = 16;
 
         Atom kNaN;
 #ifdef VMCFG_FLOAT
         Atom kFltNaN;
         Atom kFltOne;                   // needed for increment
         Atom kFltMinusOne;              // needed for decrement
         Atom kFlt4NaN;
 #endif
-        GCMember<String> workerStates[9];
+        GCMember<String> workerStates[10];
         
         GCMember<String> kExecPolicy;   // execution policy attribute
         GCMember<String> kOSR;          //    OSR threshold
         GCMember<String> cachedChars[128];
         /*@}*/
 
         Exception *exceptionAddr;
 
@@ -1722,16 +1722,21 @@ const int kBufferPadding = 16;
         /**
          * The interrupt method is called from executing code
          * when the interrupted flag is set.  interrupt()
          * MUST NOT RETURN; the caller expects a thrown exception.
          */
         virtual void interrupt(Toplevel *env, InterruptReason) = 0;
 
         /**
+         * called by host if the current interrupt should be cleared
+         */
+        void clearInterrupt();
+
+        /**
          * called by the host to raise the AS3 interrupt exception.
          * if AS3 code is executing, then soon after this call,
          * interrupt() will be invoked by the currently executing function.
          */
         void raiseInterrupt(InterruptReason reason);
 
         // return true if there is a pending interrupt of the specific InterruptReason.
         bool interruptCheckReason(InterruptReason r) const;
--- a/core/ConcurrencyGlue.cpp
+++ b/core/ConcurrencyGlue.cpp
@@ -36,32 +36,37 @@ namespace avmplus {
         mmfx_delete(this);
     }
 
     void MutexObject::State::lock(Toplevel* toplevel) {
         Isolate* isolate = toplevel->core()->getIsolate();
         if (isolate) {
             Isolate::InterruptibleState::WaitRecord record;
             Isolate::InterruptibleState::Enter state(record, &m_interruptibleState, isolate);
-            while (state.waitListHead() != &record || VMPI_recursiveMutexTryLock(&m_mutex) == false)
-            {
-                state.wait();
-                if (state.interrupted) {
-                    goto process_interrupt;
-                }
-            }
+			
+			if (m_ownerThreadID != VMPI_currentThread())
+			{
+				while (state.waitListHead() != &record || VMPI_recursiveMutexTryLock(&m_mutex) == false)
+				{
+					state.wait();
+					if (state.interrupted) {
+						goto process_interrupt;
+					}
+				}
+			}
             lockAcquired();
         }
         return;
 
 process_interrupt:
         // never long jump with InterruptibleState::Enter on the stack
         // destroy the RAII object 
         isolate->getAggregate()->processWorkerInterrupt(toplevel);
     }
+	
 
     bool MutexObject::State::tryLock()
     {
         bool result = false;
         if (m_interruptibleState.hasWaiters() == false) 
         {
             DEBUG_STATE(("thread %d calling Mutex(%d).tryLock()\n", VMPI_currentThread(), m_interruptibleState.gid));
             result = VMPI_recursiveMutexTryLock(&m_mutex);
@@ -87,23 +92,23 @@ process_interrupt:
         }
         DEBUG_STATE(("thread %d unlocking Mutex(%d)\n", VMPI_currentThread(), m_interruptibleState.gid));
         // Ok so we own the lock.
         AvmAssert(m_recursionCount > 0);
         m_recursionCount--;
 
         if (m_recursionCount == 0) {
             m_ownerThreadID = VMPI_nullThread(); 
-        } 
+			  // unlock the mutex *first* otherwise any waking thread
+			// will try the lock and go back to waiting even though 
+			// it should have acquired the lock
+			VMPI_recursiveMutexUnlock(&m_mutex); 
+			m_interruptibleState.notifyAll();  
+		} 
 
-        // unlock the mutex *first* otherwise any waking thread
-        // will try the lock and go back to waiting even though 
-        // it should have acquired the lock
-        VMPI_recursiveMutexUnlock(&m_mutex); 
-        m_interruptibleState.notifyAll();
         return true;
     }
 
     MutexObject::MutexObject(VTable* cvtable, ScriptObject* delegate) 
         : ScriptObject(cvtable, delegate)
         , m_state(NULL)
     {
     }
@@ -121,36 +126,44 @@ process_interrupt:
     // "backing state" of the MutexObject this hash is used to ensure that
     // the "highlander" principle is adhered to (there can be only one!), ensuring
     // that sending the same ActionScript object back and forth between GC address
     // space returns the same object every time.
     // Example:
     //    var mutex:Mutex = new Mutex();
     //    worker.setSharedProperty("foo", mutex) === worker.getSharedProperty("foo") // always true
     //
-    void MutexObject::ctor() 
+    void MutexObject::ctor()
     {
         m_state = mmfx_new(MutexObject::State());
-        if (!m_state->m_isValid || (core()->getIsolate() == NULL)) {
-            toplevel()->throwError(kMutexCannotBeInitialized);
+        
+        Toplevel* top = toplevel();
+        if (!(MutexClass::getMutexSupported( top ) && m_state->m_isValid)) 
+        {
+            top->throwError(kMutexCannotBeInitialized);
         }
 
-        AvmAssert(toplevel()->getInternedObject(m_state) == NULL);
-        toplevel()->internObject(m_state, this);
+        AvmAssert(top->getInternedObject(m_state) == NULL);
+        top->internObject(m_state, this);
     }
 
     MutexObject::~MutexObject() 
     {
-        // if we hold the lock we should unlock
-        bool cont = m_state->unlock();
-        while(m_state->m_recursionCount && cont)
+        // if OOM occured during ctor() mmfx_new long jumps
+        // and m_state will still be null
+        if (m_state)
         {
-            cont = m_state->unlock();
-        };
-        m_state = NULL;
+            // if we hold the lock we should unlock
+            bool cont = m_state->unlock();
+            while(m_state->m_recursionCount && cont)
+            {
+                cont = m_state->unlock();
+            };
+            m_state = NULL;
+        }
     }
   
     void MutexObject::lock()
     {
         DEBUG_STATE(("thread %d calling Mutex(%d).lock()\n", VMPI_currentThread(), m_state->m_interruptibleState.gid));
         // we continue to try and get the lock until
         // we are terminated or acquire it
         m_state->lock(toplevel());
@@ -277,30 +290,33 @@ process_interrupt:
                         state.wait(1);
                         if (state.interrupted) {
                             goto process_interrupt;
                         }
                     }
                 }
             }
 
-            TRY(toplevel->core(), kCatchAction_Rethrow)
             {
                 // re-acquire the public mutex 
-                m_mutexState->lock(toplevel);
+				Isolate::InterruptibleState::WaitRecord record;
+				Isolate::InterruptibleState::Enter state(record, &m_mutexState->m_interruptibleState, isolate);
+			
+				while (state.waitListHead() != &record || VMPI_recursiveMutexTryLock(&m_mutexState->m_mutex) == false)
+				{
+					state.wait();
+					if (state.interrupted) {
+						goto process_interrupt;
+					}
+				}
+				m_mutexState->lockAcquired();
+
                 DEBUG_STATE(("thread %d Condition(%d) re-acquired Mutex(%d)\n", VMPI_currentThread(), m_interruptibleState.gid, m_mutexState->m_interruptibleState.gid));
                 m_mutexState->m_recursionCount = saved_recursionCount;
             }
-            CATCH(Exception* e)
-            {
-                m_mutexState->m_recursionCount = saved_recursionCount;
-                toplevel->core()->throwException(e);
-            }
-            END_TRY;
-            END_CATCH;
         }
         return result;
 
 process_interrupt:
         // because we should not long jump with a InterruptibleState::Enter on the stack
         // we need to destroy the RAII object before throwing
         isolate->getAggregate()->processWorkerInterrupt(toplevel);
         return result;
@@ -324,17 +340,20 @@ process_interrupt:
     // Example:
     //    var mutex:Mutex = new Mutex()
     //    var cond:Condition = new Condition(mutex);
     //    worker.setSharedProperty("foo", cond) === worker.getSharedProperty("foo"); // always true
     //    worker.getSharedProperty("foo").mutex === mutex; // always true
     //
     void ConditionObject::ctor(GCRef<MutexObject> mutex)
     {
-        if (mutex == NULL) {
+		if (!MutexClass::getMutexSupported( toplevel() ))
+			toplevel()->throwError(kConditionCannotBeInitialized);
+
+		if (mutex == NULL) {
             toplevel()->throwArgumentError(kNullPointerError, core()->newStringLatin1("mutex"));
         }
 
         m_mutex = mutex;
         m_state = mmfx_new(ConditionObject::State(mutex->m_state));
 
         AvmAssert(toplevel()->getInternedObject(m_state) == NULL);  
         toplevel()->internObject(m_state, this);
--- a/core/ConcurrencyGlue.h
+++ b/core/ConcurrencyGlue.h
@@ -9,17 +9,16 @@
 
 #if defined(DEBUG)
 #define DEBUG_CONDITION_MUTEX
 #endif // DEBUG
 
 
 namespace avmplus {
 
-
 #if defined(DEBUG_CONDITION_MUTEX)
     #define DEBUG_STATE(_x_) do { AvmLog _x_; } while(0)
 #else
     #define DEBUG_STATE(_x_) do { } while(0)
 #endif
 
     //
     // Mutexes in ActionScript are composed of a OS level
--- a/core/Isolate-inlines.h
+++ b/core/Isolate-inlines.h
@@ -53,17 +53,16 @@ namespace avmplus
 
             // the only way this should happen is if we run out of ids 
             // (you'd need > 2 billion active workers), memory, or aggregate is in shutdown 
 			AvmAssert(isolate != NULL || parent->getAggregate()->inShutdown()); 
 		}
 
         if (isolate) {
             setIsolate(isolate);
-		    self()->toplevel()->addWorker(self());
         }
     }
 
     template<class T>
     GCRef<ScriptObject> WorkerObjectBase<T>::setIsolate(Isolate* isolate)
     {
         if (m_isolate == NULL) {
             m_isolate = isolate;
@@ -140,17 +139,17 @@ namespace avmplus
         // worker is busy creating workers during a shutdown cycle,
         // as the logic for creating an isolate will return NULL 
         // in that situation.
         if (m_isolate)
         {
             Aggregate* aggregate = m_isolate->getAggregate();
             Isolate::State code = aggregate->queryState(m_isolate);
             AvmAssert(code >= Isolate::NEW && code <= Isolate::EXCEPTION);
-            if (code == Isolate::STARTING)
+            if (code == Isolate::CANSTART || code == Isolate::STARTING)
             {
                 code = Isolate::NEW;
             }
             else if (code == Isolate::FINISHING)
             {
                 code = Isolate::RUNNING;
             }
             return self()->core()->workerStates[code];
--- a/core/Isolate.cpp
+++ b/core/Isolate.cpp
@@ -65,52 +65,52 @@ namespace avmplus
     {
     }
 
     void Aggregate::destroy()
     {
         mmfx_delete(this);
     }
     
-    void Aggregate::outOfMemoryShutdown()
+    void Aggregate::signalOutOfMemoryShutdown()
     {
         requestAggregateExit();
 		vmbase::SafepointRecord::cleanupAfterOOM();
     }
 
     bool Aggregate::requestIsolateExit(Isolate::descriptor_t desc, Toplevel* currentToplevel)
     {
         bool result = false;
         SCOPE_LOCK_NAMED(locker, m_globals.m_lock) {
             Isolate* isolate = m_globals.getIsolateForID(desc);
             // if the isolate isn't found in the global table terminate 
             // has been called previously, skip the rest.
             if (isolate == NULL) { 
                 return false; 
             }
 
-            if (isolate->m_state == Isolate::RUNNING || isolate->m_state == Isolate::STARTING) {
+            // if the isolate is in CANSTART, STARTING or RUNNING state it should be interrupted
+            if (isolate->m_state > Isolate::NEW && isolate->m_state <= Isolate::RUNNING) {
                 isolate->interrupt();
             }
             result = true;
 
             // if the isolate has not been started i.e. it is still
-            // in the NEW state then leave it in the table,
+            // in the NEW or CANSTART state then leave it in the table,
             // it will then be properly disposed of during aggregate exit.
-            if (isolate->m_state != Isolate::NEW) {
+            if (isolate->m_state > Isolate::CANSTART) {
                 SCOPE_LOCK(m_globals.m_isolateMap.m_lock) { 
 				    m_globals.orphanFor(desc);
                     m_globals.m_isolateMap.RemoveItem(desc);
                 }
             }
 
-            
-            // if the isolate is in a NEW, FAILED, ABORTED, TERMINATED, 
+            // if the isolate is in a NEW, CANSTART, FAILED, ABORTED, TERMINATED, 
             // or EXCEPTION state then we can just exit here
-            if (isolate->m_state == Isolate::NEW || isolate->m_state > Isolate::FINISHING) {
+            if (isolate->m_state <= Isolate::CANSTART || isolate->m_state > Isolate::FINISHING) {
                 return false;
             }
 
 			AvmCore* core = isolate->m_core;
             if (core == currentToplevel->core()) {
                 // calling terminate on this thread:
                 // no need to interrupt or signal as
                 // the thread is currently active (not blocked)
@@ -140,17 +140,17 @@ throw_terminated_error:
                 Aggregate* m_aggregate;
             public:
                 IsolateCoreInterrupt(Aggregate* aggregate): m_aggregate(aggregate) {}
 				
                 virtual void each(Isolate::descriptor_t , FixedHeapRef<Isolate> isolate) 
                 {
                     if (m_aggregate == isolate->m_aggregate && !isolate->isInterrupted())
 					{
-						if (isolate->m_state == Isolate::NEW) {
+                        if (isolate->m_state <= Isolate::CANSTART) {
 							m_aggregate->stateTransition(isolate, Isolate::TERMINATED);
 						}
 						else {
 
 							if (isolate->m_state < Isolate::FAILED) {
 								AvmCore* core = isolate->m_core;
 								// Ensure that the write to AvmCore::interrupted is visible to the other thread.
 
@@ -214,17 +214,17 @@ throw_terminated_error:
     
     void Aggregate::processWorkerInterrupt(Toplevel* currentToplevel)
     {
         AvmCore* core = currentToplevel->core();
         if (!core->interruptCheckReason(AvmCore::ScriptTimeout)) {
             throwWorkerTerminatedException(currentToplevel);
         }
         else {
-            core->raiseInterrupt(AvmCore::NotInterrupted); // clear existing interrupt before throwing
+            core->clearInterrupt(); // clear existing interrupt before throwing
             core->interrupt(currentToplevel, AvmCore::ScriptTimeout);
         }
     }
 
     Isolate::Isolate(Isolate::descriptor_t desc, Isolate::descriptor_t parentDesc, Aggregate* aggregate)
         : m_desc(desc)
         , m_parentDesc(parentDesc)
         , m_core(NULL)
@@ -237,72 +237,58 @@ throw_terminated_error:
 		AvmAssert(m_desc != INVALID_DESC && m_desc != POISON_DESC);
         VMPI_recursiveMutexInit(&m_interruptibleStateMutex);
     }
 
     void Aggregate::stateTransition(Isolate* isolate, Isolate::State to)
     {
         SCOPE_LOCK_NAMED(locker, m_globals.m_lock) {
             enum Isolate::State from = isolate->m_state;
-            bool verbose = false;
-            if (verbose) {
-                
-                static const char* state_names[] = {
-                    "NONE",
-                    "NEW",
-                    "STARTING",
-                    "RUNNING",
-                    "FINISHING",
-                    "TERMINATED",
-                    "FAILED",
-                    "ABORTED",
-                    "EXCEPTION"
-                };
-
-                AvmAssert(from != to);
-                fprintf(stderr, "%d: %s->%s\n", isolate->getDesc(), state_names[from], state_names[to]);
-            }
             isolate->m_state = to;
 #ifdef _DEBUG
             vmbase::VMThread* t = NULL;
 #endif // _DEBUG
             bool isolateInactive = false;
-            if (to == Isolate::STARTING) {
+            if (to == Isolate::CANSTART) {
                 AvmAssert(from == Isolate::NEW);
+            } else if (to == Isolate::STARTING) {
+                AvmAssert(from == Isolate::CANSTART);
             } else if (to == Isolate::RUNNING) {
                 AvmAssert(from < to); // FIXME this can be violated (?)
                 AvmAssert(isolate->getDesc() == m_primordialGiid || m_activeIsolateThreadMap.LookupItem(isolate->getDesc(), &t) == true); 
                 AvmAssert(isolate->m_core != NULL);
             } else if (to == Isolate::EXCEPTION) {
                 AvmAssert(from > Isolate::NEW);
                 setIsolateAsInterrupted(isolate);
                 isolate->stopRunLoop();
                 isolateInactive = true;
             } else if (to == Isolate::FAILED) {
                 AvmAssert(from == Isolate::NEW);
                 isolate->m_failed = true;
                 isolateInactive = true;
             } else if (to == Isolate::FINISHING) {
-                AvmAssert(from == Isolate::RUNNING || from == Isolate::STARTING || from == Isolate::FINISHING);
+                AvmAssert(from == Isolate::CANSTART || from == Isolate::RUNNING || from == Isolate::STARTING || from == Isolate::FINISHING);
                 AvmAssert(isolate->getDesc() == m_primordialGiid || m_activeIsolateThreadMap.LookupItem(isolate->getDesc(), &t) == true); 
 				if (from != Isolate::FINISHING)
 				{
                     setIsolateAsInterrupted(isolate);
 					isolate->stopRunLoop();
 				}
             } else if (to == Isolate::TERMINATED) {
                 AvmAssert(from == Isolate::RUNNING || from == Isolate::STARTING || from == Isolate::FINISHING || from == Isolate::NEW);
                 setIsolateAsInterrupted(isolate);
                 isolateInactive = true;
 			}
             
             if (isolateInactive) {
                 m_activeIsolateCount--;
                 locker.notifyAll();
             }
+            
+            isolate->stateChanged(to);
         }
     }
 
     void Aggregate::setIsolateAsInterrupted(Isolate* isolate) 
     {
         Isolate::lockInSafepoint(&isolate->m_interruptibleStateMutex);
         {
             Isolate::InterruptibleState* state = isolate->m_interruptibleState;
@@ -594,17 +580,25 @@ throw_terminated_error:
     {
         return m_aggregate->isPrimordial(m_desc);
     }
      
     void Isolate::run() 
     {
         // Make sure the isolate survives for the duration of the doRun() call by keeping a ref to it.
         FixedHeapRef<Isolate> handle(this);
-		doRun();
+
+        // don't run if interrupted
+        if (m_interrupted) {
+            m_aggregate->stateTransition(this, Isolate::TERMINATED);
+        }
+        else {
+            m_aggregate->stateTransition(this, Isolate::STARTING);
+		    doRun();
+        }
     }
 
     Isolate::~Isolate()
     {
 		AvmAssert(m_interruptibleState == NULL);
         AvmAssert(RefCount() == 0);
         if (m_code.length > 0) {
             for (int i = 0; i < m_code.length; i++)
@@ -879,17 +873,17 @@ throw_terminated_error:
 
         SCOPE_LOCK_NAMED(cond, m_condition) {
             // a notifyAll must occur for each call to signal
             // otherwise shutdown can be stopped waiting for
             // blocked workers.  if a signal cycle is already
             // in progress wait until it is completed and then
             // start a new one.
             while (m_signaledWaiters > 0) {
-                cond.wait(1);
+                cond.wait(0);
             }
             
             if (m_waiterCount > 0) {
                 m_signaledWaiters = m_waiterCount;
                 // mark all waiting threads as signaled so only those
                 // threads will check state and possibly wait again
                 // other threads will simply ignore the wake request
                 // and return immediately to a waiting state.
@@ -904,30 +898,30 @@ throw_terminated_error:
     }
 
     void Isolate::InterruptibleState::notify()
     {
         SCOPE_LOCK_NAMED(cond, m_condition) {
             // wait until the current signal cycle completes
             // if there is one.
             while (m_signaledWaiters > 0) {
-                cond.wait(1);
+                cond.wait(0);
             }
             DEBUG_STATE(("thread %d is calling notify on (%d)\n", VMPI_currentThread(), gid));
             cond.notify();
         }
     }
 
     void Isolate::InterruptibleState::notifyAll()
     {
         SCOPE_LOCK_NAMED(cond, m_condition) {
             // wait until the current signal cycle completes
             // if there is one.
             while (m_signaledWaiters > 0) {
-                cond.wait(1);
+                cond.wait(0);
             }
 
             DEBUG_STATE(("thread %d is calling notifyAll on (%d)\n", VMPI_currentThread(), gid));
             cond.notifyAll();
         }
     }
 
     //
@@ -970,23 +964,22 @@ throw_terminated_error:
         SCOPE_LOCK(m_globals.m_lock) {
 #ifdef _DEBUG
             vmbase::VMThread* t;
 #endif // _DEBUG
 
             AvmAssert(m_activeIsolateThreadMap.LookupItem(isolate->getDesc(), &t) == false);
             vmbase::VMThread* thread = mmfx_new(vmbase::VMThread(isolate));
             if (thread->start()) {
-				stateTransition(isolate, Isolate::STARTING);
+                stateTransition(isolate, Isolate::CANSTART);
 				m_activeIsolateThreadMap.InsertItem(isolate->getDesc(), thread);
 				result = true;
             } else {
                 // We will never try to spawn this isolate again.
 				stateTransition(isolate, Isolate::FAILED);
-					
 				mmfx_delete(thread);
                 result = false;
             }
         }
         return result;
     }
 
     void Aggregate::cleanupIsolate(Isolate* isolate)
--- a/core/Isolate.h
+++ b/core/Isolate.h
@@ -58,39 +58,40 @@ namespace avmplus
 
         bool isParentOf(const Isolate* other) const
         {
             AvmAssert(other != NULL);
             return other->m_parentDesc == m_desc;
         }
 
         virtual void copyByteCode(ByteArrayObject* array);
-        
+
         // WorkerObject type depends on the overiding class.
         virtual ScriptObject* newWorkerObject(Toplevel* toplevel) =  0;
-
+        
         bool interrupt();				// false if already interrupted
         bool isInterrupted() const;
         bool hasFailed() const;
 
         // Last phase of termination.
         virtual bool isMemoryManagementShutDown() const; 
 
         bool isPrimordial() const;
         
         enum State {
             NONE = 0, // sentinel
-            NEW = 1, 
-            STARTING = 2, 
-            RUNNING = 3, 
-            FINISHING = 4, 
-            TERMINATED = 5, 
-            FAILED = 6, 
-            ABORTED = 7, 
-            EXCEPTION = 8
+            NEW = 1,
+            CANSTART = 2,
+            STARTING = 3, 
+            RUNNING = 4, 
+            FINISHING = 5, 
+            TERMINATED = 6, 
+            FAILED = 7, 
+            ABORTED = 8, 
+            EXCEPTION = 9
         };
 
     protected:
         FixedHeapArray<uint8_t> getByteCode() const
         { 
             return m_code.values[0]; 
         }
 		
@@ -101,34 +102,35 @@ namespace avmplus
         }
 
         virtual void doRun() = 0;
 
     public:
 		descriptor_t getDesc() const { return m_desc; }
 		descriptor_t getParentDesc() const { return m_parentDesc; }
 		void resetParent() { m_parentDesc = INVALID_DESC; }
-		
+
     protected:
         typedef FixedHeapArray<char>* SharedPropertyNamep;
-		
+
         class SharedPropertyMap: public FixedHeapHashTable<SharedPropertyNamep, ChannelItem*>
         {
         public:
             SharedPropertyMap();
             virtual ~SharedPropertyMap();
         protected:
             virtual uintptr_t HashKey(SharedPropertyNamep key) const;
             virtual bool KeysEqual(SharedPropertyNamep key1, const SharedPropertyNamep key2) const;
             virtual void DestroyItem(SharedPropertyNamep key, ChannelItem* value);
         };
-		
+
         FixedHeapArray< FixedHeapArray<uint8_t> > m_code;
         
     private:
+        virtual void stateChanged(Isolate::State from) { (void)from; }
 		descriptor_t m_desc;
         descriptor_t m_parentDesc;
 
         virtual void releaseActiveResources();
  		vmbase::RecursiveMutex m_sharedPropertyLock; 
 		SharedPropertyMap m_sharedProperties;
 
     public:
@@ -159,26 +161,26 @@ namespace avmplus
              * threads to be signaled in a special way
              * by the runtime (see signal for more details)
              */ 
             struct WaitRecord
             {
                 WaitRecord() 
                     : next(NULL)
                     , signaled(false)
-    #ifdef DEBUG_CONDITION_MUTEX
+#ifdef DEBUG_CONDITION_MUTEX
                     , threadID(VMPI_currentThread())
-    #endif // DEBUG_CONDITION_MUTEX
+#endif // DEBUG_CONDITION_MUTEX
                 {}
 
                 WaitRecord* next;
                 bool signaled;
-    #ifdef DEBUG_CONDITION_MUTEX
+#ifdef DEBUG_CONDITION_MUTEX
                 vmpi_thread_t threadID;
-    #endif // DEBUG_CONDITION_MUTEX
+#endif // DEBUG_CONDITION_MUTEX
             };
 
             InterruptibleState();
             bool hasWaiters();
             void notify();
             void notifyAll();
             // signal is a specialized case of notifyAll.
             // it makes the distinction between user code
@@ -220,19 +222,19 @@ namespace avmplus
                 {
                 public:
                     ActiveInterruptibleStateHelper(Isolate* isolate, InterruptibleState* state);
                     ~ActiveInterruptibleStateHelper();
                     void unlock() const;
                     Isolate* getIsolate() const;
 
 
-        #ifdef DEBUG_INTERRUPTIBLE_STATE
-			        Isolate::descriptor_t gid;
-        #endif // DEBUG_INTERRUPTIBLE_STATE
+#if defined(DEBUG_INTERRUPTIBLE_STATE) || defined(DEBUG_CONDITION_MUTEX)
+		            Isolate::descriptor_t gid;
+#endif // DEBUG_INTERRUPTIBLE_STATE
                 private:
 
                     Isolate* m_isolate;
                     // reference to the mutex that is used to 
                     // protect the active state on isolate
                     vmpi_mutex_t* m_mutex;
                 };
                 // we must always set the isolate's active state
@@ -243,32 +245,32 @@ namespace avmplus
                 ActiveInterruptibleStateHelper m_stateSetter;
                 vmbase::MonitorLocker< vmbase::IMPLICIT_SAFEPOINT > m_monitor;
                 InterruptibleState* m_state;
                 WaitRecord* m_waitRecord;
             };
 
             vmbase::WaitNotifyMonitor& getMonitor() { return m_condition; }
 
-#ifdef DEBUG_INTERRUPTIBLE_STATE
-             int32_t gid;
+#if defined (DEBUG_INTERRUPTIBLE_STATE) || defined (DEBUG_CONDITION_MUTEX)
+            int32_t gid;
 #endif // DEBUG_INTERRUPTIBLE_STATE
 
         private:
             friend class Enter;
             // to distingush between a call to signal from runtime
             // code and user code calling notify/notifyAll
             // a waiter count and signaled waiter counts along with
             // the wait list are used.
             // when a signal cycle starts it sets the singaled waiters
             // count to the current waiters count.  
             // when a signal is requested it must first check that 
             // a signal has not already been requested and wait until
             // it is complete.
-            vmbase::WaitNotifyMonitor m_condition;
+        vmbase::WaitNotifyMonitor m_condition;
             volatile int32_t m_waiterCount;
             uint32_t m_signaledWaiters;
             // list of threads waiting on this state, in FIFO order
             WaitRecord* m_head;
             WaitRecord* m_tail;
 
 #ifdef DEBUG_INTERRUPTIBLE_STATE
             static  int32_t globalId; // global id counter
@@ -313,47 +315,47 @@ namespace avmplus
         {
             friend class Aggregate;
         public:
             Globals()
                   : m_nextGlobalIsolateId(1) 
  				  , m_idsWrapped(false)
                   , m_isolateMap(16)
             {}
-			
+
 			Isolate::descriptor_t getNewID()
 			{
 				Isolate::descriptor_t newID = m_nextGlobalIsolateId;
 				bool hadWrap = (newID == Isolate::POISON_DESC);
 				m_idsWrapped = m_idsWrapped || hadWrap;
 				
 				if (m_idsWrapped)
 				{
 					if (hadWrap)
 						m_nextGlobalIsolateId = 1;
 					
 					FixedHeapRef<Isolate> isolateRef(NULL);
 					while (m_isolateMap.LookupItem(m_nextGlobalIsolateId, &isolateRef)) 
-					{
+            {
 						m_nextGlobalIsolateId++;
 					}
 					newID = m_nextGlobalIsolateId;
-				}
-				
+            }
+
 				m_nextGlobalIsolateId++;
 				return newID;
 			}
-			
+
 			void orphanFor(Isolate::descriptor_t giid)
 			{
 				class Orphanize: public Globals::IsolateMap::Iterator
 				{
-				private:
+                private:
 					const Isolate::descriptor_t m_TargetID;
-					
+
 				public:
 					Orphanize(Isolate::descriptor_t target)
 					: m_TargetID(target)
 					{}
 					
 					virtual void each(Isolate::descriptor_t, FixedHeapRef<Isolate> isolate) 
 					{
 						if (isolate->getParentDesc() == m_TargetID)
@@ -395,23 +397,23 @@ namespace avmplus
         // shutting down the associated Aggregate.
         //
         class ActiveIsolateThreadMap: public FixedHeapHashTable<Isolate::descriptor_t, vmbase::VMThread*>
 		{
 		public:
 			ActiveIsolateThreadMap(int initialSize);
 			void cleanup();
 		};
-		
+
     public:
         Aggregate();
         virtual ~Aggregate();
         virtual void destroy();
 
-        void outOfMemoryShutdown();
+        void signalOutOfMemoryShutdown();
         bool isPrimordial(Isolate::descriptor_t giid) const;
 
         // If parent == NULL, the primordial isolate will be created.
         Isolate* newIsolate(Isolate* parent);
 
         bool spawnIsolateThread(Isolate* isolate);
 
         void initialize(AvmCore* targetCore, Isolate* isolate);
@@ -440,17 +442,17 @@ namespace avmplus
         {
             return &m_safepointMgr;
         }
         
         bool inShutdown() const
         {
             return m_inShutdown;
         }
-		
+
     private:
         void setIsolateAsInterrupted(Isolate* isolate);
 
         Globals m_globals;
 		Isolate::descriptor_t m_primordialGiid;
         int m_activeIsolateCount;
         vmbase::SafepointManager m_safepointMgr; // Currently for shared byte array only.
         bool m_inShutdown;
--- a/core/Toplevel-inlines.h
+++ b/core/Toplevel-inlines.h
@@ -8,17 +8,16 @@ namespace avmplus
 {
 
 REALLY_INLINE Toplevel::Toplevel(AbcEnv* abcEnv)
     : _traitsToAliasMap(abcEnv->core()->GetGC())
     , _abcEnv(abcEnv)
     , _scriptEntryPoints(abcEnv->core()->gc, 10)
     , _aliasToClassClosureMap(HeapHashtable::create(abcEnv->core()->GetGC()))
     , _isolateInternedObjects(WeakValueHashtable::create(abcEnv->core()->GetGC()))
-	, _workerList(abcEnv->core()->GetGC(), 5)
 {
 }
 
 REALLY_INLINE GCRef<builtinClassManifest> Toplevel::builtinClasses() const
 {
     AvmAssert(_builtinClasses != NULL);
     return GCRef<builtinClassManifest>(_builtinClasses);
 }
--- a/core/Toplevel.cpp
+++ b/core/Toplevel.cpp
@@ -1710,15 +1710,9 @@ namespace avmplus
 		{
 			return NULL;
 		}
 		else
 		{
 			return AvmCore::atomToScriptObject(value);
         }
 	}
-
-	void Toplevel::addWorker (GCRef<ScriptObject> worker)
-	{
-		_workerList.add(worker);
-	}
-
 }
--- a/core/Toplevel.h
+++ b/core/Toplevel.h
@@ -422,18 +422,16 @@ namespace avmplus
          * Native methods from the flash.net package
          */
         static void registerClassAlias(ScriptObject *script, String *aliasName, ClassClosure *cc);
         static ClassClosure* getClassByAlias(ScriptObject* script, String *aliasName);
 
  		void internObject (const FixedHeapRCObject* rep, GCRef<ScriptObject> obj);
         GCRef<ScriptObject> getInternedObject (const FixedHeapRCObject* rep) const;
 		
-		void addWorker (GCRef<ScriptObject> worker);
-
     protected:
         ClassClosure* findClassInScriptEnv(int class_id, ScriptEnv* env);
 
     private:
 
         static int parseHexChar(wchar c);
         static Stringp decode(AvmCore* core, Stringp in, bool decodeURIComponentFlag);
         static Stringp encode(AvmCore* core, Stringp in, bool encodeURIComponentFlag);
@@ -494,16 +492,15 @@ namespace avmplus
         GCMember<IntClass>          GC_POINTER(_intClass);
         GCMember<UIntClass>         GC_POINTER(_uintClass);
         GCMember<StringClass>       GC_POINTER(_stringClass);
         GCMember<HeapHashtable>     GC_POINTER(_aliasToClassClosureMap);  // maps aliasName -> ClassClosure
 
         
     protected:
         GCMember<WeakValueHashtable>  GC_POINTER(_isolateInternedObjects);
-		WeakRefList<ScriptObject>	GC_STRUCTURE(_workerList);
         GC_DATA_END(Toplevel)
     // ------------------------ DATA SECTION END
     //
     };
 }
 
 #endif /* __avmplus_Toplevel__ */
--- a/extensions/ST_workers_Promise.st
+++ b/extensions/ST_workers_Promise.st
@@ -14,13 +14,14 @@
     main=core->getIsolate();
 
 
 %%test MainWorker
     // verify the main worker can be retrieved from AvmCore
     %%verify main!=NULL
     uint32_t state=main->getAggregate()->queryState(main);
     // verify state == RUNNING
-    %%verify state==3
+    //printf("state=%d\n",state);
+    %%verify state==4
 
     %%verify main->getAvmCore() == core
     %%verify main->isParentOf(main) == false
 
--- a/extensions/SelftestExec.cpp
+++ b/extensions/SelftestExec.cpp
@@ -5806,22 +5806,23 @@ void ST_workers_Promise::prologue() {
 
 }
 void ST_workers_Promise::test0() {
     // verify the main worker can be retrieved from AvmCore
 // line 19 "ST_workers_Promise.st"
 verifyPass(main!=NULL, "main!=NULL", __FILE__, __LINE__);
     uint32_t state=main->getAggregate()->queryState(main);
     // verify state == RUNNING
-// line 22 "ST_workers_Promise.st"
-verifyPass(state==3, "state==3", __FILE__, __LINE__);
-
-// line 24 "ST_workers_Promise.st"
+    //printf("state=%d\n",state);
+// line 23 "ST_workers_Promise.st"
+verifyPass(state==4, "state==4", __FILE__, __LINE__);
+
+// line 25 "ST_workers_Promise.st"
 verifyPass(main->getAvmCore() == core, "main->getAvmCore() == core", __FILE__, __LINE__);
-// line 25 "ST_workers_Promise.st"
+// line 26 "ST_workers_Promise.st"
 verifyPass(main->isParentOf(main) == false, "main->isParentOf(main) == false", __FILE__, __LINE__);
 
 
 }
 void create_workers_Promise(AvmCore* core) { new ST_workers_Promise(core); }
 }
 }
 #endif
--- a/extensions/SelftestInit.cpp
+++ b/extensions/SelftestInit.cpp
@@ -1,11 +1,44 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is [Open Source Virtual Machine.].
+ *
+ * The Initial Developer of the Original Code is
+ * Adobe System Incorporated.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Adobe AS3 Team
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
 // Initialization code for generated selftest code
 #include "avmshell.h"
 namespace avmplus {
 #ifdef VMCFG_SELFTEST
 namespace ST_avmplus_basics {
 extern void create_avmplus_basics(AvmCore* core);
 }
 namespace ST_avmplus_builtins {
--- a/generated/avmplus-tracers.hh
+++ b/generated/avmplus-tracers.hh
@@ -3649,34 +3649,30 @@ const uint32_t Toplevel::gcTracePointerO
     offsetof(Toplevel, _isolateInternedObjects),
     offsetof(Toplevel, _mainEntryPoint),
     offsetof(Toplevel, _namespaceClass),
     offsetof(Toplevel, _numberClass),
     offsetof(Toplevel, _scriptEntryPoints),
     offsetof(Toplevel, _stringClass),
     offsetof(Toplevel, _traitsToAliasMap),
     offsetof(Toplevel, _uintClass),
-    offsetof(Toplevel, _workerList),
     offsetof(Toplevel, objectClass),
     0};
 
 MMgc::GCTracerCheckResult Toplevel::gcTraceOffsetIsTraced(uint32_t off) const
 {
     MMgc::GCTracerCheckResult result;
     (void)off;
     (void)result;
     if((result = _scriptEntryPoints.gcTraceOffsetIsTraced(off - offsetof(Toplevel,_scriptEntryPoints))) != MMgc::kOffsetNotFound) {
         return result;
     }
     if((result = _traitsToAliasMap.gcTraceOffsetIsTraced(off - offsetof(Toplevel,_traitsToAliasMap))) != MMgc::kOffsetNotFound) {
         return result;
     }
-    if((result = _workerList.gcTraceOffsetIsTraced(off - offsetof(Toplevel,_workerList))) != MMgc::kOffsetNotFound) {
-        return result;
-    }
     return MMgc::GC::CheckOffsetIsInList(off,gcTracePointerOffsets,19);
 }
 #endif // DEBUG
 
 bool Toplevel::gcTrace(MMgc::GC* gc, size_t _xact_cursor)
 {
     (void)gc;
     (void)_xact_cursor;
@@ -3696,17 +3692,16 @@ bool Toplevel::gcTrace(MMgc::GC* gc, siz
     gc->TraceLocation(&_isolateInternedObjects);
     gc->TraceLocation(&_mainEntryPoint);
     gc->TraceLocation(&_namespaceClass);
     gc->TraceLocation(&_numberClass);
     _scriptEntryPoints.gcTrace(gc);
     gc->TraceLocation(&_stringClass);
     _traitsToAliasMap.gcTrace(gc);
     gc->TraceLocation(&_uintClass);
-    _workerList.gcTrace(gc);
     gc->TraceLocation(&objectClass);
     return false;
 }
 
 
 
 #ifdef DEBUG
 const uint32_t Traits::gcTracePointerOffsets[] = {
index f2221fee0c3921cc44eb257dd9a3cf62c676a271..49b6e1a266f39c4fbca6e34806066106f8e31200
GIT binary patch
literal 55791
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
S)~qcuYl}+%B4O1)&HoR0JH>zi
--- a/generated/builtin.cpp
+++ b/generated/builtin.cpp
@@ -11449,18 +11449,18 @@ const uint8_t builtin_abc_data[55791] = 
  101,  23, 115, 101, 116,  80, 114, 111, 112, 101, 114, 116, 121,  73, 115,  69,
  110, 117, 109, 101, 114,  97,  98, 108, 101,  14, 116, 111,  76, 111,  99,  97,
  108, 101,  83, 116, 114, 105, 110, 103,   8, 116, 111,  83, 116, 114, 105, 110,
  103,   7, 118,  97, 108, 117, 101,  79, 102,  18,  95, 100, 111, 110, 116,  69,
  110, 117, 109,  80, 114, 111, 116, 111, 116, 121, 112, 101,  14,  95, 105, 115,
   80, 114, 111, 116, 111, 116, 121, 112, 101,  79, 102,  15,  95, 104,  97, 115,
   79, 119, 110,  80, 114, 111, 112, 101, 114, 116, 121,  21,  95, 112, 114, 111,
  112, 101, 114, 116, 121,  73, 115,  69, 110, 117, 109, 101, 114,  97,  98, 108,
- 101,   3, 238, 138, 148,   4, 105, 110, 105, 116,   3, 238, 138, 174,   5,  95,
- 105, 110, 105, 116,   3,  65,  80,  73,   3,  54,  56,  54,   5,  67, 108,  97,
+ 101,   3, 238, 138, 148,   4, 105, 110, 105, 116,   3, 238, 138, 176,   5,  95,
+ 105, 110, 105, 116,   3,  65,  80,  73,   3,  54,  56,  56,   5,  67, 108,  97,
  115, 115,   8,  70, 117, 110,  99, 116, 105, 111, 110,   4,  99,  97, 108, 108,
    5,  97, 112, 112, 108, 121,  22, 102, 117, 110,  99, 116, 105, 111, 110,  32,
   70, 117, 110,  99, 116, 105, 111, 110,  40,  41,  32, 123, 125,  19,  99, 114,
  101,  97, 116, 101,  69, 109, 112, 116, 121,  70, 117, 110,  99, 116, 105, 111,
  110,   7,  99, 112, 112,  99,  97, 108, 108,   9,  78,  97, 109, 101, 115, 112,
   97,  99, 101,   6, 112, 114, 101, 102, 105, 120,   5, 102,  97, 108, 115, 101,
    5,  69, 114, 114, 111, 114,   9,  84, 121, 112, 101,  69, 114, 114, 111, 114,
   26,  66, 111, 111, 108, 101,  97, 110,  46, 112, 114, 111, 116, 111, 116, 121,
index e8c235373d8055b8b2c4d3743b3fc3f82e541659..6090254d6622ae3f6a4828d75c0e11c1c6561e2b
GIT binary patch
literal 18126
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
--- a/generated/shell_toplevel.cpp
+++ b/generated/shell_toplevel.cpp
@@ -2779,17 +2779,17 @@ const uint8_t shell_toplevel_abc_data[18
  101, 120, 105,  99,  97, 108,  83,  99, 111, 112, 101, 115,  31,  83,  97, 109,
  112, 108, 101, 114,  83,  99, 114, 105, 112, 116,  58,  58, 103, 101, 116,  76,
  101, 120, 105,  99,  97, 108,  83,  99, 111, 112, 101, 115,  12, 103, 101, 116,
   83,  97, 118, 101, 100,  84, 104, 105, 115,  27,  83,  97, 109, 112, 108, 101,
  114,  83,  99, 114, 105, 112, 116,  58,  58, 103, 101, 116,  83,  97, 118, 101,
  100,  84, 104, 105, 115,  15, 103, 101, 116,  77,  97, 115, 116, 101, 114,  83,
  116, 114, 105, 110, 103,  30,  83,  97, 109, 112, 108, 101, 114,  83,  99, 114,
  105, 112, 116,  58,  58, 103, 101, 116,  77,  97, 115, 116, 101, 114,  83, 116,
- 114, 105, 110, 103,   3,  54,  56,  54,  17, 102, 108,  97, 115, 104,  46, 116,
+ 114, 105, 110, 103,   3,  54,  56,  56,  17, 102, 108,  97, 115, 104,  46, 116,
  114,  97,  99, 101,  58,  84, 114,  97,  99, 101,   3,  79,  70,  70,   7,  77,
   69,  84,  72,  79,  68,  83,  17,  77,  69,  84,  72,  79,  68,  83,  95,  87,
   73,  84,  72,  95,  65,  82,  71,  83,  17,  77,  69,  84,  72,  79,  68,  83,
   95,  65,  78,  68,  95,  76,  73,  78,  69,  83,  27,  77,  69,  84,  72,  79,
   68,  83,  95,  65,  78,  68,  95,  76,  73,  78,  69,  83,  95,  87,  73,  84,
   72,  95,  65,  82,  71,  83,   4,  70,  73,  76,  69,   8,  76,  73,  83,  84,
   69,  78,  69,  82,   8, 115, 101, 116,  76, 101, 118, 101, 108,   8, 103, 101,
  116,  76, 101, 118, 101, 108,  11, 115, 101, 116,  76, 105, 115, 116, 101, 110,
--- a/shell/avmshell.cpp
+++ b/shell/avmshell.cpp
@@ -105,22 +105,30 @@ namespace avmshell
 
             avmplus::FixedHeapRef<Shell> instance(mmfx_new(Shell));
             instance->parseCommandLine(argc, argv);
 
             if (instance->settings.do_log)
               initializeLogging(instance->settings.numfiles > 0 ? instance->settings.filenames[0] : "AVMLOG");
 
 #ifdef VMCFG_WORKERTHREADS
-            if (instance->settings.numworkers == 1 && instance->settings.numthreads == 1 && instance->settings.repeats == 1)
-                instance->newIsolate(NULL)->run();
+            if (instance->settings.numworkers == 1 && instance->settings.numthreads == 1 && instance->settings.repeats == 1) 
+            {
+                avmplus::Isolate* isolate = instance->newIsolate(NULL); 
+                instance->stateTransition(isolate, avmplus::Isolate::CANSTART);
+                isolate->run();
+            }
             else
+            {
                 instance->multiWorker(instance->settings);
+            }
 #else
-			instance->newIsolate(NULL)->run();
+            avmplus::Isolate* isolate = instance->newIsolate(NULL); 
+            instance->stateTransition(isolate, avmplus::Isolate::CANSTART);
+			isolate->run();
 #endif
             instance->waitUntilNoIsolates();
             // Shell is refcounted now
             //mmfx_delete(instance);
         }
 
         MMgc::GCHeap::Destroy();
         MMgc::GCHeap::EnterLockDestroy();
@@ -262,17 +270,16 @@ namespace avmshell
             MMgc::GC *gc = mmfx_new( MMgc::GC(MMgc::GCHeap::GetGCHeap(), gcconfig) );
             
             MMGC_GCENTER(gc);
 
             ShellCore* shell = new ShellCoreImpl(gc, settings, true);
             this->initialize(shell);
 
             avmplus::EnterSafepointManager enterSafepointManager(shell);
-            aggregate->stateTransition(this, avmplus::Isolate::STARTING);
 
             ShellToplevel* toplevel = shell->setup(settings);
             // inlined singleWorkerHelper
             if (toplevel == NULL) // FIXME abort?
 				Platform::GetInstance()->exit(1);
 
 #ifdef VMCFG_SELFTEST
         if (settings.do_selftest) {