Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@@ -5,11 +5,6 @@ set(SOURCES
../common.cpp
)
if(CLR_CMAKE_PLATFORM_UNIX)
list(APPEND SOURCES
../platform.unix.cpp)
endif()
add_library(bootstrapper STATIC ${SOURCES})
# Install the static bootstrapper library

View File

@@ -7,11 +7,6 @@ set(SOURCES
../common.cpp
)
if(CLR_CMAKE_PLATFORM_UNIX)
list(APPEND SOURCES
../platform.unix.cpp)
endif()
add_library(bootstrappercpp STATIC ${SOURCES})
# Install the static bootstrappercpp library

View File

@@ -211,7 +211,7 @@ extern "C" void RhpUniversalTransition_DebugStepTailCall()
}
extern "C" void CCWAddRef()
{
throw "CCWAddRef";
throw "CCWAddRef";
}
void* RtRHeaderWrapper();
@@ -231,10 +231,10 @@ extern "C" bool REDHAWK_PALAPI PalInit();
#define DLL_PROCESS_ATTACH 1
extern "C" BOOL WINAPI RtuDllMain(HANDLE hPalInstance, DWORD dwReason, void* pvReserved);
extern "C" int32_t RhpEnableConservativeStackReporting();
extern "C" void RhpShutdown();
extern "C" int32_t RhpEnableConservativeStackReporting();
#ifndef CPPCODEGEN
extern "C" bool RhpRegisterCoffModule(void * pModule,
@@ -254,6 +254,7 @@ extern "C" void* WINAPI PalGetModuleHandleFromPointer(void* pointer);
extern "C" void GetRuntimeException();
extern "C" void FailFast();
extern "C" void AppendExceptionStackFrame();
extern "C" void GetSystemArrayEEType();
typedef void(*pfn)();
@@ -262,11 +263,13 @@ static const pfn c_classlibFunctions[] = {
&FailFast,
nullptr, // &UnhandledExceptionHandler,
&AppendExceptionStackFrame,
nullptr, // &CheckStaticClassConstruction,
&GetSystemArrayEEType,
};
#endif // !CPPCODEGEN
extern "C" void InitializeModules(void* osModule, void ** modules, int count);
extern "C" void InitializeModules(void* osModule, void ** modules, int count, void ** pClasslibFunctions, int nClasslibFunctions);
#if defined(_WIN32)
extern "C" int __managed__Main(int argc, wchar_t* argv[]);
@@ -282,8 +285,10 @@ int main(int argc, char* argv[])
if (!RtuDllMain(NULL, DLL_PROCESS_ATTACH, NULL))
return -1;
#if defined(CPPCODEGEN)
if (!RhpEnableConservativeStackReporting())
return -1;
#endif // CPPCODEGEN
#ifndef CPPCODEGEN
void *osModule;
@@ -308,22 +313,26 @@ int main(int argc, char* argv[])
#endif
#ifndef CPPCODEGEN
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)));
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)), (void **)&c_classlibFunctions, _countof(c_classlibFunctions));
#else // !CPPCODEGEN
InitializeModules(nullptr, (void**)RtRHeaderWrapper(), 2);
InitializeModules(nullptr, (void**)RtRHeaderWrapper(), 2, nullptr, 0);
#endif // !CPPCODEGEN
int retval;
#ifdef CPPCODEGEN
try
#endif
{
retval = __managed__Main(argc, argv);
}
#ifdef CPPCODEGEN
catch (const char* &e)
{
printf("Call to an unimplemented runtime method; execution cannot continue.\n");
printf("Method: %s\n", e);
retval = -1;
}
#endif
#ifdef CPPCODEGEN
__reverse_pinvoke_return(&frame);

View File

@@ -1,125 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <cstdlib>
#include <cstring>
#include <stdint.h>
//
// Temporary stubs for Windows PInvoke functions not ported to Unix yet
//
// UNIXTODO: Port System.Private.Interop to Unix https://github.com/dotnet/corert/issues/669
extern "C"
{
int32_t WideCharToMultiByte(uint32_t CodePage, uint32_t dwFlags, uint16_t* lpWideCharStr, int32_t cchWideChar, intptr_t lpMultiByteStr, int32_t cbMultiByte, intptr_t lpDefaultChar, intptr_t lpUsedDefaultChar)
{
throw "WideCharToMultiByte";
}
int32_t MultiByteToWideChar(uint32_t CodePage, uint32_t dwFlags, const uint8_t * lpMultiByteStr, int32_t cbMultiByte, uint16_t* lpWideCharStr, int32_t cchWideChar)
{
throw "MultiByteToWideChar";
}
void CoTaskMemFree(void* m)
{
free(m);
}
intptr_t CoTaskMemAlloc(intptr_t size)
{
return (intptr_t)malloc(size);
}
}
extern "C"
{
// TODO: Remove this when when we replace the references of
// Interop.mincore.GetLastError with Marsha.GetLastWin32Error
// CoreLib System.Text and System.Threading in CoreLib
uint32_t GetLastError()
{
throw "GetLastError";
}
uint32_t WaitForMultipleObjectsEx(uint32_t, void*, uint32_t, uint32_t, uint32_t)
{
throw "WaitForMultipleObjectsEx";
}
void CoCreateGuid()
{
throw "CoCreateGuid";
}
void CoGetApartmentType()
{
throw "CoGetApartmentType";
}
void CoUnmarshalInterface()
{
throw "CoUnmarshalInterface";
}
void CoMarshalInterface()
{
throw "CoMarshalInterface";
}
void CoGetMarshalSizeMax()
{
throw "CoGetMarshalSizeMax";
}
void CreateEventExW()
{
throw "CreateEventExW";
}
void OutputDebugStringW()
{
}
uint32_t GetCurrentThreadId()
{
return 42;
}
uint32_t RhCompatibleReentrantWaitAny(uint32_t alertable, uint32_t timeout, uint32_t count, void* pHandles)
{
throw "RhCompatibleReentrantWaitAny";
}
void EnumDynamicTimeZoneInformation()
{
throw "EnumDynamicTimeZoneInformation";
}
void GetDynamicTimeZoneInformation()
{
throw "GetDynamicTimeZoneInformation";
}
void GetDynamicTimeZoneInformationEffectiveYears()
{
throw "GetDynamicTimeZoneInformationEffectiveYears";
}
void GetTimeZoneInformationForYear()
{
throw "GetTimeZoneInformationForYear";
}
void GetCPInfo()
{
throw "GetCPInfo";
}
void EventWriteTransfer()
{
throw "EventWriteTransfer";
}
}

View File

@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include <inttypes.h>
inline uint16_t SWAP16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
inline uint32_t SWAP32(uint32_t x)
{
return (x >> 24) |
((x >> 8) & 0x0000FF00L) |
((x & 0x0000FF00L) << 8) |
(x << 24);
}

View File

@@ -1,5 +1,3 @@
#pragma optimize( "", off )
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

View File

@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
enum DebuggerGcProtectionMessage : uint32_t
{
RequestBufferReady = 2,
ConservativeReportingBufferReady = 3,
};
enum DebuggerGcProtectionRequestKind : uint16_t
{
EnsureConservativeReporting = 1,
RemoveConservativeReporting = 2,
};
struct GcProtectionMessage
{
DebuggerGcProtectionMessage commandCode;
uint32_t unused; /* To make the data structure 64 bit aligned */
uint64_t bufferAddress;
};
struct GcProtectionRequest
{
DebuggerGcProtectionRequestKind kind;
uint16_t size;
uint32_t identifier;
uint64_t address;
};

View File

@@ -43,6 +43,16 @@ void DebugEventSource::SendModuleLoadEvent(Module* pModule)
SendRawEvent(&payload);
}
void DebugEventSource::SendModuleLoadEvent(void* pAddressInModule)
{
if(!EventEnabled(DEBUG_EVENT_TYPE_LOAD_MODULE))
return;
DebugEventPayload payload;
payload.type = DEBUG_EVENT_TYPE_LOAD_MODULE;
payload.ModuleLoadUnload.pModuleHeader = (CORDB_ADDRESS)pAddressInModule;
SendRawEvent(&payload);
}
void DebugEventSource::SendModuleUnloadEvent(Module* pModule)
{
if(!EventEnabled(DEBUG_EVENT_TYPE_UNLOAD_MODULE))

View File

@@ -25,6 +25,7 @@ class Module;
class DebugEventSource
{
public:
static void SendModuleLoadEvent(void* addressInModule);
static void SendModuleLoadEvent(Module* pModule);
static void SendModuleUnloadEvent(Module* pModule);
static void SendExceptionThrownEvent(CORDB_ADDRESS faultingIP, CORDB_ADDRESS faultingFrameSP);

View File

@@ -4,44 +4,32 @@
#include "common.h"
#include "CommonTypes.h"
#include "CommonMacros.h"
#include "DebuggerHook.h"
#include "DebugEventSource.h"
#include "Debug.h"
GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
#ifndef DACCESS_COMPILE
// TODO: Tab to space, overall, just to make sure I will actually do it :)
// TODO: This structure needs to match with DBI
struct FuncEvalParameterCommand
{
// TODO: Consider giving these command code a good enumeration to define what they really are
UInt32 commandCode;
UInt32 unused; /* To make the data structure 64 bit aligned */
UInt64 bufferAddress;
};
/* static */ DebuggerProtectedBufferList* DebuggerHook::s_debuggerProtectedBuffers = nullptr;
// TODO: This structure needs to match with DBI
struct GcProtectionRequest
{
UInt16 type;
UInt16 size;
UInt64 address;
};
/* static */ DebuggerOwnedHandleList* DebuggerHook::s_debuggerOwnedHandleList = nullptr;
/* static */ UInt32 DebuggerHook::s_debuggeeInitiatedHandleIdentifier = 2;
/* static */ void DebuggerHook::OnBeforeGcCollection()
{
if (g_numGcProtectionRequests > 0)
{
// The debugger has some request with respect to GC protection.
// The debugger has some requests with respect to GC protection.
// Here we are allocating a buffer to store them
GcProtectionRequest* requests = new (nothrow) GcProtectionRequest[g_numGcProtectionRequests];
// TODO: We need to figure out how to communicate this broken promise to the debugger
// Notifying the debugger the buffer is ready to use
FuncEvalParameterCommand command;
command.commandCode = 2;
GcProtectionMessage command;
command.commandCode = DebuggerGcProtectionMessage::RequestBufferReady;
command.bufferAddress = (uint64_t)requests;
DebugEventSource::SendCustomEvent((void*)&command, sizeof(command));
@@ -50,23 +38,75 @@ struct GcProtectionRequest
// The debugger has filled the requests array
for (uint32_t i = 0; i < g_numGcProtectionRequests; i++)
{
if (requests[i].type == 1)
if (requests[i].kind == DebuggerGcProtectionRequestKind::EnsureConservativeReporting)
{
// If the request requires extra memory, allocate for it
requests[i].address = (uint64_t)new (nothrow) uint8_t[requests[i].size];
// The debugger will handle the case when address is nullptr (we have to break our promise)
}
}
command.commandCode = 3;
// TODO: Consider an optimization to eliminate this message when they is nothing required from the
// debugger side to fill
command.commandCode = DebuggerGcProtectionMessage::ConservativeReportingBufferReady;
DebugEventSource::SendCustomEvent((void*)&command, sizeof(command));
// ... debugger magic happen here again ...
for (uint32_t i = 0; i < g_numGcProtectionRequests; i++)
{
if (requests[i].type == 1)
if (requests[i].kind == DebuggerGcProtectionRequestKind::EnsureConservativeReporting)
{
// What shall I do?
DebuggerProtectedBufferList* tail = DebuggerHook::s_debuggerProtectedBuffers;
s_debuggerProtectedBuffers = new (std::nothrow) DebuggerProtectedBufferList();
if (s_debuggerProtectedBuffers == nullptr)
{
// TODO: We cannot handle the debugger request to protect a buffer (we have to break our promise)
// TODO: We need to figure out how to communicate this broken promise to the debugger
}
else
{
s_debuggerProtectedBuffers->address = requests[i].address;
s_debuggerProtectedBuffers->size = requests[i].size;
s_debuggerProtectedBuffers->identifier = requests[i].identifier;
s_debuggerProtectedBuffers->next = tail;
}
}
else if (requests[i].kind == DebuggerGcProtectionRequestKind::RemoveConservativeReporting)
{
DebuggerProtectedBufferList* prev = nullptr;
DebuggerProtectedBufferList* curr = DebuggerHook::s_debuggerProtectedBuffers;
while (true)
{
if (curr == nullptr)
{
// The debugger is trying to remove a conservatively reported buffer that does not exist
break;
}
if (curr->identifier == requests[i].identifier)
{
DebuggerProtectedBufferList* toDelete = curr;
if (prev == nullptr)
{
// We are trying to remove the head of the linked list
DebuggerHook::s_debuggerProtectedBuffers = curr->next;
}
else
{
prev->next = curr->next;
}
delete toDelete;
break;
}
else
{
prev = curr;
curr = curr->next;
}
}
}
}
@@ -74,4 +114,27 @@ struct GcProtectionRequest
}
}
/* static */ UInt32 DebuggerHook::RecordDebuggeeInitiatedHandle(void* objectHandle)
{
DebuggerOwnedHandleList* head = new (nothrow) DebuggerOwnedHandleList();
if (head == nullptr)
{
return 0;
}
head->handle = objectHandle;
head->identifier = DebuggerHook::s_debuggeeInitiatedHandleIdentifier;
head->next = s_debuggerOwnedHandleList;
s_debuggerOwnedHandleList = head;
s_debuggeeInitiatedHandleIdentifier += 2;
return head->identifier;
}
EXTERN_C REDHAWK_API UInt32 __cdecl RhpRecordDebuggeeInitiatedHandle(void* objectHandle)
{
return DebuggerHook::RecordDebuggeeInitiatedHandle(objectHandle);
}
#endif // !DACCESS_COMPILE

View File

@@ -17,10 +17,29 @@
#ifndef DACCESS_COMPILE
struct DebuggerProtectedBufferList
{
UInt64 address;
UInt16 size;
UInt32 identifier;
struct DebuggerProtectedBufferList* next;
};
struct DebuggerOwnedHandleList
{
void* handle;
UInt32 identifier;
struct DebuggerOwnedHandleList* next;
};
class DebuggerHook
{
public:
static void OnBeforeGcCollection();
static void OnBeforeGcCollection();
static UInt32 RecordDebuggeeInitiatedHandle(void* handle);
static DebuggerProtectedBufferList* s_debuggerProtectedBuffers;
static DebuggerOwnedHandleList* s_debuggerOwnedHandleList;
static UInt32 s_debuggeeInitiatedHandleIdentifier;
};
#endif //!DACCESS_COMPILE

View File

@@ -25,6 +25,8 @@
#include "threadstore.h"
#include "threadstore.inl"
#include "stressLog.h"
#include "rhbinder.h"
#include "eetype.h"
// Find the code manager containing the given address, which might be a return address from a managed function. The
// address may be to another managed function, or it may be to an unmanaged function. The address may also refer to
@@ -38,7 +40,6 @@ static ICodeManager * FindCodeManagerForClasslibFunction(void * address)
if (pCodeManager != NULL)
return pCodeManager;
// @TODO: CORERT: Do we need to make this work for CoreRT?
// Less common, we will look for the address in any of the sections of the module. This is slower, but is
// necessary for EEType pointers and jump stubs.
Module * pModule = pRI->FindModuleByAddress(address);
@@ -67,7 +68,7 @@ COOP_PINVOKE_HELPER(Boolean, RhpEHEnumNext, (EHEnum* pEHEnum, EHClause* pEHClaus
// Unmanaged helper to locate one of two classlib-provided functions that the runtime needs to
// implement throwing of exceptions out of Rtm, and fail-fast. This may return NULL if the classlib
// found via the provided address does not have the necessary exports.
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFunctionId functionId))
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunctionFromCodeAddress, (void * address, ClasslibFunctionId functionId))
{
// Find the code manager for the given address, which is an address into some managed module. It could
// be code, or it could be an EEType. No matter what, it's an address into a managed module in some non-Rtm
@@ -83,6 +84,30 @@ COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFun
return pCodeManager->GetClasslibFunction(functionId);
}
// Unmanaged helper to locate one of two classlib-provided functions that the runtime needs to
// implement throwing of exceptions out of Rtm, and fail-fast. This may return NULL if the classlib
// found via the provided address does not have the necessary exports.
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunctionFromEEtype, (EEType * pEEtype, ClasslibFunctionId functionId))
{
if (pEEtype->HasTypeManager())
{
return pEEtype->GetTypeManagerPtr()->AsTypeManager()->GetClasslibFunction(functionId);
}
else
{
RuntimeInstance * pRI = GetRuntimeInstance();
Module * pModule = pRI->FindModuleByAddress(pEEtype);
if (pModule != NULL)
{
return pModule->GetClasslibFunction(functionId);
}
else
{
return NULL;
}
}
}
COOP_PINVOKE_HELPER(void, RhpValidateExInfoStack, ())
{
Thread * pThisThread = ThreadStore::GetCurrentThread();

View File

@@ -197,3 +197,11 @@ COOP_PINVOKE_HELPER(Int32, RhWaitForFullGCComplete, (Int32 millisecondsTimeout))
int timeout = millisecondsTimeout == -1 ? INFINITE : millisecondsTimeout;
return GCHeapUtilities::GetGCHeap()->WaitForFullGCComplete(millisecondsTimeout);
}
COOP_PINVOKE_HELPER(Int64, RhGetGCSegmentSize, ())
{
size_t first = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(Boolean_true);
size_t second = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(Boolean_false);
return (first > second) ? first : second;
}

View File

@@ -84,7 +84,7 @@ COOP_PINVOKE_CDECL_HELPER(void *, memcpyGCRefsWithWriteBarrier, (void * dest, co
ASSERT(src != nullptr);
InlineForwardGCSafeCopy(dest, src, len);
InlinedBulkWriteBarrier(dest, (UInt32)len);
InlinedBulkWriteBarrier(dest, len);
// memcpy returns the destination buffer
return dest;
@@ -110,7 +110,7 @@ COOP_PINVOKE_CDECL_HELPER(void *, memcpyAnyWithWriteBarrier, (void * dest, const
// Move memory, in a way that is compatible with a move onto the heap, but
// does not require the destination pointer to be on the heap.
COOP_PINVOKE_HELPER(void, RhBulkMoveWithWriteBarrier, (uint8_t* pDest, uint8_t* pSrc, int cbDest))
COOP_PINVOKE_HELPER(void, RhBulkMoveWithWriteBarrier, (uint8_t* pDest, uint8_t* pSrc, size_t cbDest))
{
if (pDest <= pSrc || pSrc + cbDest <= pDest)
InlineForwardGCSafeCopy(pDest, pSrc, cbDest);
@@ -128,7 +128,7 @@ void GCSafeZeroMemory(void * dest, size_t len)
void GCSafeCopyMemoryWithWriteBarrier(void * dest, const void *src, size_t len)
{
InlineForwardGCSafeCopy(dest, src, len);
InlinedBulkWriteBarrier(dest, (UInt32)len);
InlinedBulkWriteBarrier(dest, len);
}
void REDHAWK_CALLCONV RhpBulkWriteBarrier(void* pMemStart, UInt32 cbMemSize)

View File

@@ -162,7 +162,7 @@ FORCEINLINE void InlineCheckedWriteBarrier(void * dst, void * ref)
InlineWriteBarrier(dst, ref);
}
FORCEINLINE void InlinedBulkWriteBarrier(void* pMemStart, UInt32 cbMemSize)
FORCEINLINE void InlinedBulkWriteBarrier(void* pMemStart, size_t cbMemSize)
{
// Check whether the writes were even into the heap. If not there's no card update required.
// Also if the size is smaller than a pointer, no write barrier is required.

View File

@@ -37,8 +37,9 @@ COOP_PINVOKE_HELPER(Object *, RhHandleGet, (OBJECTHANDLE handle))
COOP_PINVOKE_HELPER(Object *, RhHandleGetDependent, (OBJECTHANDLE handle, Object **ppSecondary))
{
*ppSecondary = GetDependentHandleSecondary(handle);
return ObjectFromHandle(handle);
Object *pPrimary = ObjectFromHandle(handle);
*ppSecondary = (pPrimary != NULL) ? GetDependentHandleSecondary(handle) : NULL;
return pPrimary;
}
COOP_PINVOKE_HELPER(void, RhHandleSetDependentSecondary, (OBJECTHANDLE handle, Object *pSecondary))

View File

@@ -76,6 +76,7 @@ enum class ClasslibFunctionId
UnhandledExceptionHandler = 2,
AppendExceptionStackFrame = 3,
CheckStaticClassConstruction = 4,
GetSystemArrayEEType = 5,
};
class ICodeManager

View File

@@ -110,9 +110,9 @@ COOP_PINVOKE_HELPER(UInt32, RhGetLoadedOSModules, (Array * pResultArray))
ReaderWriterLock::ReadHolder read(&GetRuntimeInstance()->GetTypeManagerLock());
RuntimeInstance::OsModuleList osModules = GetRuntimeInstance()->GetOsModuleList();
RuntimeInstance::OsModuleList *osModules = GetRuntimeInstance()->GetOsModuleList();
for (RuntimeInstance::OsModuleList::Iterator iter = osModules.Begin(); iter != osModules.End(); iter++)
for (RuntimeInstance::OsModuleList::Iterator iter = osModules->Begin(); iter != osModules->End(); iter++)
{
if (pResultArray && (cModules < cResultArrayElements))
pResultElements[cModules] = iter->m_osModule;
@@ -660,7 +660,7 @@ COOP_PINVOKE_HELPER(Boolean, RhpArrayCopy, (Array * pSourceArray, Int32 sourceIn
else
InlineBackwardGCSafeCopy(pDestinationData, pSourceData, size);
InlinedBulkWriteBarrier(pDestinationData, (UInt32)size);
InlinedBulkWriteBarrier(pDestinationData, size);
}
else
{

View File

@@ -831,6 +831,14 @@ REDHAWK_PALIMPORT size_t REDHAWK_PALAPI PalGetLargestOnDieCacheSize(UInt32_BOOL
REDHAWK_PALIMPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_ HANDLE hTemplateModule, UInt32 templateRva, size_t templateSize, _Outptr_result_bytebuffer_(templateSize) void** newThunksOut);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalMarkThunksAsValidCallTargets(
void *virtualAddress,
int thunkSize,
int thunksPerBlock,
int thunkBlockSize,
int thunkBlocksPerMapping);
REDHAWK_PALIMPORT UInt32 REDHAWK_PALAPI PalCompatibleWaitAny(UInt32_BOOL alertable, UInt32 timeout, UInt32 count, HANDLE* pHandles, UInt32_BOOL allowReentrantWait);

View File

@@ -408,6 +408,19 @@ void EECodeManager::EnumGcRefs(MethodGcInfoPointers * pMethodInfo,
if ((pCursor == NULL) || (*pCursor == 0xFF))
return;
UInt32 commonVarCount = 0;
PTR_UInt8 commonVarStart = NULL;
if (pMethodInfo->GetGCInfoHeader()->HasCommonVars())
{
// remember only the count and the start of the table, to avoid allocating memory
// this is a design compromise
commonVarCount = VarInt::ReadUnsigned(pCursor);
commonVarStart = pCursor;
for (UInt32 i = 0; i < commonVarCount; i++)
{
VarInt::SkipUnsigned(pCursor);
}
}
// -------------------------------------------------------------------------------------------------------
// Decode the method GC info
@@ -516,7 +529,8 @@ ContinueUnconditionally:
// a. l - last descriptor
// b. SSSS - set of "local slots" #0 - #3 - local slot 0 is at offset -8 from the last pushed
// callee saved register, local slot 1 is at offset - 16, etc - in other words, these are the
// slots normally used for locals
// slots normally used for locals. The non-sensical encoding with SSSS = 0000 is reserved for
// the "common vars" case under 8 below.
//
// 5. 10l0ssss - "local slot" encoding
// a. l - last descriptor
@@ -545,6 +559,15 @@ ContinueUnconditionally:
// e. IIIIIII - interior scratch register mask for { rax, rcx, rdx, r8, r9, r10, r11 } iff 'i' is 1
// f. PPPPPPP - pinned scratch register mask for { rax, rcx, rdx, r8, r9, r10, r11 } iff 'p' is 1
//
// 8. 10z10000 [ common var index ] - "common var" encoding - the common var index references a root string
// common to several call sites
// a. z - common var index is 0
// b. common var index - 0-based index referring to one of the "common var" root strings.
// only present if z-bit is 0
//
// this encoding is case 4, "local stack slot set", with the set SSSS = 0
// this case is non-sensical and hence unused for case 4
//
PTR_UInt8 pbCallsiteString = pbCallsiteStringBlob + (int)infoOffset;
bool isLastEncoding;
@@ -567,7 +590,40 @@ ContinueUnconditionally:
case 0x80:
// case 4 -- "local slot set"
// case 5 -- "local slot"
ReportLocalSlots(b, pContext, hCallback, pMethodInfo->GetGCInfoHeader());
// case 8 -- "common var"
if ((b & 0xDF) == 0x90)
{
// case 8 -- "common var"
UInt32 commonVarIndex = 0;
if ((b & 0x20) == 0)
{
// obtain the 0 - based index
commonVarIndex = VarInt::ReadUnsigned(pCursor);
ASSERT(commonVarIndex < commonVarCount);
}
// skip the info offsets for the common var strings before ours
// this is a linear search, but the number of common vars should be
// significantly smaller than the number of call sites,
// plus SkipUnsigned is pretty fast, so we should be ok.
pCursor = commonVarStart;
for (UInt32 i = 0; i < commonVarIndex; i++)
{
VarInt::SkipUnsigned(pCursor);
}
// read the info offset for our common var string
infoOffset = VarInt::ReadUnsigned(pCursor);
// continue reading at that location - this is analogous to a tail call...
pCursor = pbCallsiteStringBlob + infoOffset;
isLastEncoding = false;
}
else
{
ReportLocalSlots(b, pContext, hCallback, pMethodInfo->GetGCInfoHeader());
}
break;
case 0xC0:
if ((b & 0xC7) == 0xC2)

Some files were not shown because too many files have changed in this diff Show More