示例#1
0
void ObjectMemory::deallocate(OTE* ote)
{
	#ifdef _DEBUG
		ASSERT(!ote->isFree());
		if (Interpreter::executionTrace)
		{
			tracelock lock(TRACESTREAM);
			TRACESTREAM << ote << " (" << hex << (UINT)ote << "), refs " << dec << (int)ote->m_count << ", is being deallocated" << endl;
		}
	#endif

	ASSERT(!isPermanent(ote));
	// We can have up to 256 different destructors (8 bits)
	switch (ote->heapSpace())
	{
		case OTEFlags::NormalSpace:
			freeChunk(ote->m_location);
 			releasePointer(ote);
			break;

		case OTEFlags::VirtualSpace:
			::VirtualFree(static_cast<VirtualObject*>(ote->m_location)->getHeader(), 0, MEM_RELEASE);
 			releasePointer(ote);
			break;

		case OTEFlags::BlockSpace:
			Interpreter::m_otePools[Interpreter::BLOCKPOOL].deallocate(ote);
			break;

		case OTEFlags::ContextSpace:
			// Return it to the interpreter's free list of contexts
			Interpreter::m_otePools[Interpreter::CONTEXTPOOL].deallocate(ote);
			break;

		case OTEFlags::DWORDSpace:
			Interpreter::m_otePools[Interpreter::DWORDPOOL].deallocate(ote);
			break;

		case OTEFlags::HeapSpace:
			//_asm int 3;
			HARDASSERT(FALSE);
			break;
		
		case OTEFlags::FloatSpace:
			Interpreter::m_otePools[Interpreter::FLOATPOOL].deallocate(ote);
			break;

		case OTEFlags::PoolSpace:
		{
			MWORD size = ote->sizeOf();
			HARDASSERT(size <= MaxSmallObjectSize);
			freeSmallChunk(ote->m_location, size);
			releasePointer(ote);
		}
		break;

		default:
			ASSERT(false);
	}
}
示例#2
0
// The receiver has terminated. Remove from the Processor's Pending Terminations
// list. Answer whether the process was actually on that list.
void OverlappedCall::RemoveFromPendingTerminations()
{
	ProcessOTE* oteProc = pendingTerms()->remove(m_oteProcess);
	if (oteProc == m_oteProcess)
	{
		Process* myProc = oteProc->m_location;
		HARDASSERT(myProc->Thread() == this);
		myProc->ClearThread();

		// Return it to the scheduling queues - we resume it to cause a scheduling decision to be made. 
		Interpreter::resume(oteProc);
		// Remove the reference that was from the pending terminations list
		oteProc->countDown();
	}
	else
	{
		HARDASSERT(oteProc->isNil());
	}

	m_oteProcess->countDown();
	m_oteProcess = (ProcessOTE*)Pointers.Nil;

	// Remove the call from the active list as it is being destroyed - I don't think we need
	// the lock anymore
	{
		//CMonitorLock lock(s_listMonitor);
		Unlink();
	}
}
示例#3
0
// Callback proc for MM timers
// N.B. This routine is called from a separate thread (in Win32), rather than in
// interrupt time, but careful coding is still important. The recommended 
// list of routines is limited to:
//		EnterCriticalSection	ReleaseSemaphore
//		LeaveCriticalSection	SetEvent
//		timeGetSystemTime		timeGetTime
//		OutputDebugString		timeKillEvent
//		PostMessage				timeSetEvent
//
// "If a Win32 low-level audio callback [we are using mm timers here] shares data 
// with other code, a Critical Section or similar mutual exclusion mechanism should 
// be used to protect the integrity of the data".
// Access to the asynchronous semaphore array is protected by a critical section
// in the asynchronousSignal and CheckProcessSwitch routines. We don't really care
// that much about the timerID
void CALLBACK Interpreter::TimeProc(UINT uID, UINT /*uMsg*/, DWORD /*dwUser*/, DWORD /*dw1*/, DWORD /*dw2*/)
{
	// Avoid firing a timer which has been cancelled (or is about to be cancelled!)
	// We use an InterlockedExchange() to set the value to 0 so that the main thread
	// can recognise that the timer has fired without race conditions

	if (_InterlockedExchange(reinterpret_cast<SHAREDLONG*>(&timerID), 0) != 0)
	{
		// If not previously killed (which is very unlikely except in certain exceptional
		// circumstances where the timer is killed at the exact moment it is about to fire)
		// then go ahead and signal the semaphore and the wakeup event

		// We mustn't access Pointers from an async thread when object memory is compacting
		// as the Pointer will be wrong
		GrabAsyncProtect();

		SemaphoreOTE* timerSemaphore = Pointers.TimingSemaphore;
		HARDASSERT(!ObjectMemoryIsIntegerObject(timerSemaphore));
		HARDASSERT(!timerSemaphore->isFree());
		HARDASSERT(timerSemaphore->m_oteClass == Pointers.ClassSemaphore);

		// Asynchronously signal the required semaphore asynchronously, which will be detected
		// in sync. with the dispatching of byte codes, and properly signalled
		asynchronousSignalNoProtect(timerSemaphore);
		// Signal the timing Event, in case the idle process has put the VM to sleep
		SetWakeupEvent();

		RelinquishAsyncProtect();
	}
	else
		// An old timer (which should have been cancelled) has fired
		trace("Old timer %d fired, current %d\n", uID, timerID);
}
示例#4
0
void OverlappedCall::PerformCall()
{
	// Must only be called from the overlapped thread
	HARDASSERT(::GetCurrentThreadId() == m_dwThreadId);

	// Run a call - this will finish by calling SignalCompletion, which will return to it
	// and it (after placing the return value on the stack) then returns here.
	Oop retVal = asyncDLL32Call(m_pMethod, m_nArgCount, this, &m_interpContext);

	HARDASSERT(m_oteProcess->m_location->Thread() == this);

	if (retVal != NULL)
	{
		#if TRACING == 1
		{
			TRACELOCK();
			TRACESTREAM << std::hex << GetCurrentThreadId() << L": Completed " << *m_pMethod << "; " << *this << std::endl;
		}
		#endif

		InterpreterRegisters& regs = Interpreter::GetRegisters();
		ASSERT(m_interpContext.m_pActiveProcess == regs.m_pActiveProcess);
		regs.StoreSPInFrame();
	}
	else
	{
		#if TRACING == 1
		{
			TRACELOCK();
			TRACESTREAM << std::hex << GetCurrentThreadId() << L": Call failed;  " << GetLastErrorText() << std::endl;
		}
		#endif

		// The call failed as if it were a primitive failure - the args have
		// not been popped and we need to activate the backup smalltalk code. 
		// However, since the calling Process is in a wait state, we need to 
		// notify the main thread to wake it up
		m_bCallPrimitiveFailed = true;
		NotifyInterpreterOfCallReturn();
		WaitForInterpreter();
	}

	#ifdef _DEBUG
		//Interpreter::checkReferences(m_interpContext);
	#endif

	CallFinished();

	// We don't use any of the old context after here, so even if this thread is immediately
	// reused before it gets a chance to suspend itself, it wont matter
	VERIFY(::SetEvent(m_hEvtCompleted));
}
示例#5
0
// Start off the thread, answering whether it worked or not
bool OverlappedCall::BeginThread()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	HARDASSERT(m_hThread == 0);
	// N.B. Start it suspended
	m_hThread = (HANDLE)_beginthreadex(
							/*security=*/		NULL, 
							/*stack_size=*/		0,
							/*start_address*/	ThreadMain,
							/*arglist=*/		this,
							/*initflag=*/		0, //CREATE_SUSPENDED,
							/*thrdaddr=*/		reinterpret_cast<UINT*>(&m_dwThreadId));
	return m_hThread != 0;
}
示例#6
0
///////////////////////////////////////////////////////////////////////////////
// The call on the worker thread has returned to the assembler call primitive.
// We can't complete the call until the main thread is ready to accept it, so 
// we must notify it that there is a call pending completion, and wait for it 
// to reactivate the blocked process associated with this overlapped call.
//
void OverlappedCall::OnCallReturned()
{
	// Must always be called from the worker thread
	HARDASSERT(::GetCurrentThreadId() == m_dwThreadId);

	NotifyInterpreterOfCallReturn();

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId() << L": OnCallReturned, waiting to complete; " << *this << std::endl;
	}
	#endif

	//if (inPrim) DebugBreak();

	WaitForInterpreter();

	if (GetProcess()->Thread() != this || m_state != Running)
	{
		HARDASSERT(FALSE);
		::DebugCrashDump(L"Terminated overlapped call got though to completion (%#x)\nPlease contact Object Arts.", GetProcess()->Thread());
		RaiseException(SE_VMTERMINATETHREAD, EXCEPTION_NONCONTINUABLE, 0, NULL);
	}

	// We should now be running to the exclusion of the interpreter main thread, and no other
	// threads should be accessing any of the interpreter or object memory state

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId() << L": OnCallReturned, completing; " << *this << std::endl;
	}
	#endif

	// OK, now ready to pop args and push result on stack (in sync with main thread)
	InterpreterRegisters& activeContext = Interpreter::GetRegisters();
	// The process must be the active one in order to complete
	HARDASSERT(m_interpContext.m_pActiveProcess == activeContext.m_pActiveProcess);

	if (m_interpContext.m_stackPointer != activeContext.m_stackPointer)
	{
		DebugCrashDump(L"Overlapped call stack modified before could complete!");
		DEBUGBREAK();
	}

	// Our event will be signalled again when we return to the 
}
示例#7
0
void OverlappedCall::OnActivateProcess()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	// Probably need 3 states - nothing pending, request pending, completion pending
	if (m_bCompletionRequestPending && CanComplete())
	{
		m_bCompletionRequestPending = false;

		if (m_bCallPrimitiveFailed)
		{
			m_bCallPrimitiveFailed = false;

			ASSERT(m_interpContext.m_stackPointer == Interpreter::m_registers.m_stackPointer);
			ASSERT(m_interpContext.m_basePointer == Interpreter::m_registers.m_basePointer);
			Interpreter::m_registers.m_oopNewMethod = m_interpContext.m_oopNewMethod;
			Interpreter::activateNewMethod(m_interpContext.m_oopNewMethod->m_location);
		}

		// Let the overlapped thread continue
		::SetEvent(m_hEvtGo);

		// And wait for it to finish (non-alertable since we don't want other completions to interfere)
		DWORD dwRet = ::WaitForSingleObject(m_hEvtCompleted, INFINITE);
		if (dwRet != WAIT_OBJECT_0)
			trace(L"%#x: OverlappedCall(%#x) completion wait terminated abnormally with %#x\n", GetCurrentThreadId(), this, dwRet);
	}
}
示例#8
0
void ObjectMemory::PopulateZct()
{
	HARDASSERT(m_nZctEntries <= 0);

	// To build the new Zct all we need do is countDown() everything in the current process 
	// stack. Any counts that dropped to zero, will get put back in the new Zct.
	m_nZctEntries = 0;

#ifdef _DEBUG
	bool bLast = alwaysReconcileOnAdd;
	alwaysReconcileOnAdd = false;
#endif

	// This will populate the Zct with all objects ref'd only from the active process stack
	Interpreter::DecStackRefs();
#ifdef _DEBUG
	alwaysReconcileOnAdd = bLast;
	//CHECKREFSNOFIX
#endif

	if (m_nZctEntries > (m_nZctHighWater - m_nZctHighWater/4))
	{
		// More than 75% full, then grow it
		GrowZct();
	}
	else if ((m_nZctHighWater > (int)ZctMinSize) && (m_nZctEntries < m_nZctHighWater/4))
	{
		// Less than 25% full, so shrink it
		ShrinkZct();
	}

	// Reconciliation complete
	m_bIsReconcilingZct = false;
}
示例#9
0
void OverlappedCall::Init()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	m_hEvtGo = NewAutoResetEvent();
	m_hEvtCompleted = NewAutoResetEvent();
	BeginThread();
}
示例#10
0
bool OverlappedCall::CanComplete()
{
	// Only Process safe if called from main thread
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	InterpreterRegisters& activeContext = Interpreter::GetRegisters();
	HARDASSERT(m_interpContext.m_pActiveProcess == activeContext.m_pActiveProcess);

	if (m_nSuspendCount > 0 || m_state != Running)
		return false;

	if (m_interpContext.m_pActiveFrame != activeContext.m_pActiveFrame)
		return false;

	HARDASSERT(m_interpContext.m_stackPointer == activeContext.m_stackPointer);
	return true;
}
示例#11
0
bool OverlappedCall::Initiate(CompiledMethod* pMethod, unsigned argCount)
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId() << L": Initiate; " << *this << std::endl;
	}
	#endif

	// Note that the callDepth member examined by IsInCall() method is only  accessed 
	// from the main thread, or when the main thread is blocked waiting for call 
	// completion on the worker thread, therefore it needs no synchronisation
	if (IsInCall())
		// Nested overlapped calls are not currently supported
		return false;

	m_nCallDepth++;

	// Now save down contextual information
	m_pMethod = pMethod;
	m_nArgCount = argCount;
	ASSERT(m_oteProcess == Interpreter::actualActiveProcessPointer());
	// Copy context from Interpreter
	// ?? Not sure we'll need all this
	m_interpContext = Interpreter::GetRegisters();

	// As we are about to suspend the process, we must also store down the active frame into
	// the suspended frame, and update the active frame with the current IP/SP.
	m_interpContext.PrepareToSuspendProcess();

	Process* proc = m_oteProcess->m_location;

	// Block the process on its own private Semaphore - this simplifies the completion
	// handling since all that is needed is to async signal the Semaphore from the
	// background thread, and then let the process activation code (in process.cpp)
	// spot that an overlapped call completion is pending. However it does create
	// a ref. count issue since the Semaphore may be the only ref. to the process, and
	// the process is probably the only ref. to the Semaphore.
	Interpreter::QueueProcessOn(m_oteProcess, reinterpret_cast<LinkedListOTE*>(proc->OverlapSemaphore()));

	// OK to start the async. operation now
	// We don't use Suspend/Resume because if thread is not suspended yet 
	// (i.e. it hasn't reached its SuspendThread() call), then calling Resume() here
	// will do nothing, and the thread will suspend itself for ever!
	::SetEvent(m_hEvtGo);

	TODO("Try a deliberate SwitchToThread here to see effect of call completing before we reschedule")

	// Reschedule as we probably need another process to run
	if (Interpreter::schedule() == m_oteProcess)
		DebugBreak();

	//CHECKREFERENCES
	return true;
}
示例#12
0
void ObjectMemory::GrowZct()
{
	TRACE("ZCT overflow at %d entries (%d in use), growing to %d\n", m_nZctHighWater, m_nZctEntries, m_nZctHighWater*2);
	m_nZctHighWater <<= 1;
	// Reserve and high water must be powers of 2, so this should be unless about to overflow reserve
	HARDASSERT((DWORD)m_nZctHighWater <= ZctReserve);
	m_pZct = static_cast<OTE**>(::VirtualAlloc(m_pZct, m_nZctHighWater*sizeof(OTE*), MEM_COMMIT, PAGE_READWRITE));
	if (!m_pZct)
		RaiseFatalError(IDP_ZCTRESERVEFAIL, 2, m_nZctHighWater, ZctReserve);
}
示例#13
0
// Allocate an OverlappedCall from the pool, or create a new one if none available
OverlappedCall* OverlappedCall::New(ProcessOTE* oteProcess)
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	//CMonitorLock lock(s_listMonitor);

	OverlappedCall* answer = new OverlappedCall(oteProcess);
	s_activeList.AddFirst(answer);
	return answer;
}
示例#14
0
OTE* __fastcall ObjectMemory::recursiveFree(OTE* rootOTE)
{
	HARDASSERT(!isIntegerObject(rootOTE));
	HARDASSERT(!isPermanent(rootOTE));
	HARDASSERT(!rootOTE->isFree());
	HARDASSERT(rootOTE->m_flags.m_count == 0);

#ifndef _AFX
	if (rootOTE->isFinalizable())
	{
		finalize(rootOTE);
		rootOTE->beUnfinalizable();
	}
	else
#endif
	{
		// Deal with the class first, as this is now held in the OTE
		recursiveCountDown(reinterpret_cast<POTE>(rootOTE->m_oteClass));

		if (rootOTE->isPointers())
		{
			// Recurse through referenced objects as necessary
			const MWORD lastPointer = rootOTE->getWordSize();
			Oop* pFields = reinterpret_cast<Oop*>(rootOTE->m_location);
			// Start after the header (only includes size now, which is not an Oop)
			for (MWORD i = ObjectHeaderSize; i < lastPointer; i++)
			{
				Oop fieldPointer = pFields[i];
				if (!isIntegerObject(fieldPointer))
				{
					OTE* fieldOTE = reinterpret_cast<OTE*>(fieldPointer);
					recursiveCountDown(fieldOTE);
				}
			}
		}

		deallocate(rootOTE);
	}

	return rootOTE;		// Important for some assembler routines - will be non-zero, so can act as TRUE
}
示例#15
0
void OverlappedCall::ReincrementProcessReferences()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	//CMonitorLock lock(s_listMonitor);
	OverlappedCall* next = s_activeList.First();
	while (next)
	{
		next->m_oteProcess->countUp();
		next = next->Next();
	}
}
示例#16
0
// Attempt to resume the thread
DWORD OverlappedCall::Resume()
{
	HARDASSERT(::GetCurrentThreadId() != m_dwThreadId);
	#if TRACING == 1
	{
		tracelock lock(::thinDump);
		::thinDump << std::hex << GetCurrentThreadId()<< L": Resume; " << *this << std::endl;
	}
	#endif
	InterlockedDecrement(&m_nSuspendCount);
	return ResumeThread();
}
示例#17
0
void OverlappedCall::MarkRoots()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	//CMonitorLock lock(s_listMonitor);
	OverlappedCall* next = s_activeList.First();
	while (next)
	{
		ObjectMemory::MarkObjectsAccessibleFromRoot(reinterpret_cast<POTE>(next->m_oteProcess));
		next = next->Next();
	}
}
示例#18
0
OverlappedCall::~OverlappedCall()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId() << L": Destroy " << *this << std::endl;
	}
	#endif

	//HARDASSERT(m_oteProcess->isNil());
}
示例#19
0
Oop* __fastcall Interpreter::primitiveAsyncDLL32Call(Oop* const, unsigned argCount)
{
	CompiledMethod* method = m_registers.m_oopNewMethod->m_location;

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << L"primAsync32: Prepare to call " << *method << L" from " << Interpreter::actualActiveProcessPointer() << std::endl;
	}
	#endif

	OverlappedCall* pCall = OverlappedCall::Do(method, argCount);
	if (pCall == NULL)
		// Nested overlapped calls are not supported
		return primitiveFailure(0);

	HARDASSERT(newProcessWaiting());

	// The overlapped call may already have returned, in which case a process switch
	// will not occur, so we must notify the overlapped call that it can complete as 
	// it will not receive a notification from either finishing the handling of an interrupt
	// or by switching back to the process
	if (!CheckProcessSwitch())
	{
		HARDASSERT(pCall->m_nCallDepth == 1);
		pCall->OnActivateProcess();
	}

	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << L"registers.sp = " << m_registers.m_stackPointer<< L" frame.sp = " <<
				m_registers.m_pActiveFrame->stackPointer() << std::endl;
	}
	#endif

	return m_registers.m_stackPointer;
}
示例#20
0
// Note that this is only called on shutdown
void OverlappedCall::TerminateThread()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	QueueTerminate();
	DWORD dwWaitRet = ::WaitForSingleObject(m_hThread, s_dwTerminateTimeout); dwWaitRet;
	
	#if TRACING == 1
	{
		tracelock lock(::thinDump);
		::thinDump << GetCurrentThreadId()<< L": " << *this<< L" terminated (" << dwWaitRet<< L")" << std::endl;
	}
	#endif
}
示例#21
0
void OverlappedCall::Term()
{
	HARDASSERT(::GetCurrentThreadId() == m_dwThreadId);

	if (m_hThread)
	{
		::CloseHandle(m_hThread);
		m_hThread = NULL;
		::CloseHandle(m_hEvtGo);
		m_hEvtGo = NULL;
		::CloseHandle(m_hEvtCompleted);
		m_hEvtCompleted = NULL;
	}
}
示例#22
0
// Static entry point required by _beginthreadex()
unsigned __stdcall OverlappedCall::ThreadMain(void* pvClosure)
{
	HARDASSERT(::GetCurrentThreadId() != Interpreter::MainThreadId());

	// Take over the initial reference (while thread is running, 
	// this keeps a reference on the OverlappedCall object which will then
	// be released when the smart pointer goes out of scope at the end of
	// this function, at which point the call will normally be deleted,
	// unless that is something else is holding a reference to it.)
	OverlappedCallPtr pThis(static_cast<OverlappedCall*>(pvClosure), false);

	// N.B. OC may not actually deleted as may still be ref'd from APC queue, etc
	return pThis->TryMain();
}
示例#23
0
void Interpreter::CancelSampleTimer()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	if (m_hSampleTimer != NULL)
	{
		if (!::DeleteTimerQueueTimer(NULL, m_hSampleTimer, INVALID_HANDLE_VALUE))
		{
			DWORD dwErr = GetLastError();
			dwErr;
		}
		m_hSampleTimer = NULL;
	}
}
示例#24
0
// Answer the index of the last occuppied OT entry
unsigned __stdcall ObjectMemory::lastOTEntry()
{
	HARDASSERT(m_pOT);
//	HARDASSERT(m_nInCritSection > 0);

	unsigned i = m_nOTSize-1;
	const OTE* pOT = m_pOT;
	while (pOT[i].isFree())
	{
		ASSERT(i > 0);
		i--;
	}

	return i;
}
示例#25
0
// Compact an object by updating all the Oops it contains using the
// forwarding pointers in the old OT.
void ObjectMemory::compactObject(OTE* ote)
{
	// We shouldn't come in here unless OTE already fixed for this object
	HARDASSERT(ote >= m_pOT && ote < m_pFreePointerList);

	// First fix up the class (remember that the new object pointer is stored in the
	// old one's object location slot
	compactOop(ote->m_oteClass);

	if (ote->isPointers())
	{
		VariantObject* varObj = static_cast<VariantObject*>(ote->m_location);
		const MWORD lastPointer = ote->pointersSize();
		for (MWORD i = 0; i < lastPointer; i++)
		{
			// This will get nicely optimised by the Compiler
			Oop fieldPointer = varObj->m_fields[i];

			// We don't need to visit SmallIntegers and objects we've already visited
			if (!isIntegerObject(fieldPointer))
			{
				OTE* fieldOTE = reinterpret_cast<OTE*>(fieldPointer);
				// If pointing at a free'd object ,then it has been moved
				if (fieldOTE->isFree())
				{
					// Should be one of the old OT entries, pointing outside the o
					Oop movedTo = reinterpret_cast<Oop>(fieldOTE->m_location);
					HARDASSERT(movedTo >= (Oop)m_pOT && movedTo < (Oop)m_pFreePointerList);
					// Get the new OTE from the old ...
					varObj->m_fields[i] = movedTo;
				}
			}
		}
	}
	// else, we don't even need to look at the body of byte objects any more
}
示例#26
0
void OverlappedCall::compact()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	ObjectMemory::compactOop(m_oteProcess);
	#if TRACING == 1
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId() << L"Compacting " << *this << std::endl;
	}
	#endif

	//ObjectMemory::compactOop(m_interpContext.m_oopMessageSelector);
	ObjectMemory::compactOop(m_interpContext.m_oopNewMethod);
}
示例#27
0
// Static initialization of async call support
void OverlappedCall::Initialize()
{
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	CRegKey rkOverlap;
	if (OpenDolphinKey(rkOverlap, L"Overlapped")==ERROR_SUCCESS)
	{
		rkOverlap.QueryDWORDValue(L"TerminateTimeout", s_dwTerminateTimeout);
		s_dwTerminateTimeout = max(s_dwTerminateTimeout, 100);
	}
	else
	{
		s_dwTerminateTimeout = 500;
	}
}
示例#28
0
void OverlappedCall::WaitForInterpreter()
{
	// Wait for main thread to process the async signal and permit us to continue
	DWORD dwRet;
	while ((dwRet = ::WaitForSingleObjectEx(m_hEvtGo, 5000, TRUE)) != WAIT_OBJECT_0)
	{
		thinDump << std::hex << GetCurrentThreadId() << L": OnCallReturned, wait interrupted (" << dwRet << "); " << *this << std::endl;
		if (dwRet == WAIT_ABANDONED)
		{
			// Event deleted, etc, so terminate the thread
			RaiseException(SE_VMTERMINATETHREAD, EXCEPTION_NONCONTINUABLE, 0, NULL);
		}

		// Interrupted to process an APC (probably a suspend/terminate) or due to a timeout
		HARDASSERT(dwRet == WAIT_IO_COMPLETION || dwRet == WAIT_TIMEOUT);
	}
}
示例#29
0
// Static clean up async call support on shutdown
void OverlappedCall::Uninitialize()
{
	// Access to the pool lists must only be from the main thread
	HARDASSERT(::GetCurrentThreadId() == Interpreter::MainThreadId());

	// NOTE: As the threads exit, they unlink the overlapped call object
	// from the active list. To do this they need to enter the list
	// monitor, so we have to be careful to avoid a deadlock here by not
	// holding that monitor while enumerating

	// Terminate all overlapped call threads associated with processes
	OverlappedCallPtr next = RemoveFirstFromList(s_activeList);
	while (next)
	{
		next->TerminateThread();
		next = RemoveFirstFromList(s_activeList);
	}
}
示例#30
0
// Used by an overlapped thread to suspend itself
void OverlappedCall::SuspendThread()
{
	// Should only be called from the overlapped call thread itself for safety
	HARDASSERT(::GetCurrentThreadId() == m_dwThreadId);

	// Only really suspend if there is at least one suspend still pending (an intervening
	// resume may revoke the pending suspend)
	if (m_nSuspendCount > 0)
	{
		DWORD dwRet = ::SuspendThread(GetCurrentThread());
		dwRet;
#if TRACING == 1
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId()<< L": Suspending (count=" << m_nSuspendCount << "); " << *this << dwRet << std::endl;
	}
	else
	{
		TRACELOCK();
		TRACESTREAM << std::hex << GetCurrentThreadId()<< L": Suspend ignored (count=" << m_nSuspendCount << "); " << *this << std::endl;
#endif
	}
}