9/11 CHAPTER 4 Extracting Types from Assemblies
1. 运行时加载DLL。
2. 加载 dll 的步骤。
3. GAC 加载 强命名 dll。
4. 可用 gacutil 来管理 GAC 。
5. 加载步骤可配置。
9/15
1. redirect bind
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="echo" publicKeyToken="fcd14a8abe06f0d2" culture="neutral" /> <bindingRedirect oldVersion="2.0.0.0" newVersion="1.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
2. Validating Assemblies for Consistency. 包括 PE validation, metadata validation.
3. AppDomain, SystemDomain, SharedDomain. 用 C++ 实现, 父类 BaseDomain
SystemDomain 有 ExecuteMainMethod 方法。
4. Agile Components. 对象状态能够在域边界间传递的对象。 Agile components 包括 strings, generics, type hanles, security objects, localization tables, components that are part of the remoting infrastructure.
5. Agile Components 位于 SystemDomain.
6. Assembly 需要被解析并加载到 CLI 中才能运行, 但是 CLI 自身也是一段需要加载的代码。 这就是经典的 Bootstrapping 问题。 C 实现。 clix.exe 代码如下:
DWORD Launch(WCHAR* pFileName, WCHAR* pCmdLine) { WCHAR exeFileName[MAX_PATH + 1]; DWORD dwAttrs; DWORD dwError; DWORD nExitCode; dwAttrs = ::GetFileAttributesW(pFileName); if (dwAttrs == INVALID_FILE_ATTRIBUTES) { dwError = ::GetLastError(); } else if ((dwAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) { dwError = ERROR_FILE_NOT_FOUND; } else { dwError = ERROR_SUCCESS; } if (dwError == ERROR_FILE_NOT_FOUND) { // If the file doesn't exist, append a '.exe' extension and // try again. const WCHAR *exeExtension = L".exe"; if (wcslen(pFileName) + wcslen(exeExtension) < sizeof(exeFileName) / sizeof(WCHAR)) { wcscpy(exeFileName, pFileName); wcscat(exeFileName, exeExtension); dwAttrs = ::GetFileAttributesW(exeFileName); if (dwAttrs == INVALID_FILE_ATTRIBUTES) { dwError = ::GetLastError(); } else if ((dwAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) { dwError = ERROR_FILE_NOT_FOUND; } else { pFileName = exeFileName; dwError = ERROR_SUCCESS; } } } if (dwError != ERROR_SUCCESS) { // We can't find the file, or there's some other problem. Exit with an error. fwprintf(stderr, L"%s: ", pFileName); DisplayMessageFromSystem(dwError); return 1; // error } nExitCode = _CorExeMain2(NULL, 0, pFileName, NULL, pCmdLine); // _CorExeMain2 never returns with success _ASSERTE(nExitCode != 0); DisplayMessageFromSystem(::GetLastError()); return nExitCode; }通过这段代码将 assembly 加载到 CLI, 再把返回的代码加载到操作系统中。
11/19
Interface IFoo is a simple interface consisting of one method, Bar. Upon load time, the Interface
will be assigned a unique Interface ID.
Once a method (such as InvokeMethod) is JIT compiled, the JIT will ask the runtime for a token to
call the method. The runtime hands the JIT an indirect cell pointer, and creates a Lookup Stub for that
callsite, which will inevitably pass through a Dispatch Token unique to that callsite to the Generic
Resolver. The Lookup Stub is then shared for other instances of this callsite type.
When the JIT compiled code is executed, the Lookup Stub is called via the Indirect Cell, and passes
through the hardcoded Dispatch Token to the Generic Resolver.
The Generic Resolver looks inside the Dispatch Token and pulls out the Interface ID and the
Interface¡¦s Slot Map index. It then looks up the objects Slot Map through the DispatchMap pointer,
and matches the Interface ID and Slot Map index number to the object¡¦s vtable index.
The Generic Resolver then creates both the Dispatch and Resolver stubs unique to that callsite. The
Dispatch Stub contains a check for type equivocation and a jump if true to the pointer that exists in the
objects vtable, and a jump if false to the Resolver stub.
If the type equivocation test in the Dispatch Stub fails, the Resolver Stub is called. The Resolver
checks its local cache to see if it has seen this failed case before, and invokes the cached callsite
receiver if found, otherwise it calls the Generic Resolver to resolve the mapping, and generate a new
Resolver Stub cache entry.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms721625(v=vs.85).aspx#_security_security_descriptor_gly
http://www.codeproject.com/Articles/30648/Demo-on-CLR-Profiling
https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/hardware/mt219729(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/hardware/dn553412(v=vs.85).aspx
https://blogs.msdn.microsoft.com/salvapatuel/2007/10/12/design-memory-working-set-explored/
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/solving-memory-problems/index