summaryrefslogtreecommitdiff
path: root/src/vm/gcheaputilities.h
diff options
context:
space:
mode:
authorSean Gillespie <sean@swgillespie.me>2017-02-24 10:12:26 -0800
committerGitHub <noreply@github.com>2017-02-24 10:12:26 -0800
commit6f6fda958dac38896abe9487def2242add822809 (patch)
treee9b2eed3562a07635a868c01289f3732b609dc38 /src/vm/gcheaputilities.h
parent3392356945aabd5a3ebac5317ff4a0e0361dc9ad (diff)
downloadcoreclr-6f6fda958dac38896abe9487def2242add822809.tar.gz
coreclr-6f6fda958dac38896abe9487def2242add822809.tar.bz2
coreclr-6f6fda958dac38896abe9487def2242add822809.zip
[Local GC] Move workstation GC DAC globals to a struct shared between GC and DAC (#9255)
* [Local GC] Move workstation GC DAC globals to a struct shared between the GC and the DAC * (Some) code review feedback and bug fixes for issues found while debugging on OSX * Address some code review feedback: 1. Make g_gcDacGlobals a pointer and dacvar on the VM side, so that publishing the GC dac vars is done atomically (through a pointer assignment). This fixes a race that Noah noticed. 2. Remove the requirement for the GC's generation class struct to be known at compile-time, by using a dacvar as the size of the generation class at run-time (for pointer arithmetic) 3. Move all DAC-interesting fields to be at the start of GC internal classes, so that the DAC does not need to know the size or exact layout of the class past the fields it cares about. * Split the definition of the size of several arrays across the SOS/DAC and GC/DAC interfaces, and add static asserts that they are the same * Repair the Windows Release build * Implement the GC DAC scheme for Server GC and eliminate the duplicate GC dac vars * Some work * Decouple use of the GC generation table from a write barrier by having the EE store a copy of the global during initialization * Actually make it work with server GC * Checkpoint * Checkpoint where everything works * Code cleanup * Fix debugger test failures * Additional code cleanup * Address code review feedback by adding a static assert and standardizing the way that we iterate over the generation table * Repair the Windows x86 build * Revert "Decouple use of the GC generation table from a write barrier by having the EE store a copy of the global during initialization" This reverts commit 573f61a16b4fa8c2fc4c568c0b968a921230f31c. * Revert "Repair the Windows x86 build" This reverts commit 188c22d87e1d65abf00ab8fa28f46ad607a9028f. * Partial revert, move `generation_table` back the global namespace for a single-proc allocation helper * Fix a debugger test failure * Repair crash dump scenarios
Diffstat (limited to 'src/vm/gcheaputilities.h')
-rw-r--r--src/vm/gcheaputilities.h39
1 files changed, 17 insertions, 22 deletions
diff --git a/src/vm/gcheaputilities.h b/src/vm/gcheaputilities.h
index e76a21173c..f85bd73fed 100644
--- a/src/vm/gcheaputilities.h
+++ b/src/vm/gcheaputilities.h
@@ -34,6 +34,21 @@ extern "C" bool g_sw_ww_enabled_for_gc_heap;
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+// g_gc_dac_vars is a structure of pointers to GC globals that the
+// DAC uses. It is not exposed directly to the DAC.
+extern GcDacVars g_gc_dac_vars;
+
+// Instead of exposing g_gc_dac_vars to the DAC, a pointer to it
+// is exposed here (g_gcDacGlobals). The reason for this is to avoid
+// a problem in which a debugger attaches to a program while the program
+// is in the middle of initializing the GC DAC vars - if the "publishing"
+// of DAC vars isn't atomic, the debugger could see a partially initialized
+// GcDacVars structure.
+//
+// Instead, the debuggee "publishes" GcDacVars by assigning a pointer to g_gc_dac_vars
+// to this global, and the DAC will read this global.
+typedef DPTR(GcDacVars) PTR_GcDacVars;
+GPTR_DECL(GcDacVars, g_gcDacGlobals);
// GCHeapUtilities provides a number of static methods
// that operate on the global heap instance. It can't be
@@ -112,27 +127,6 @@ public:
#endif // FEATURE_SVR_GC
}
- // Gets the maximum generation number by reading the static field
- // on IGCHeap. This should only be done by the DAC code paths - all other code
- // should go through IGCHeap::GetMaxGeneration.
- //
- // The reason for this is that, while we are in the early stages of
- // decoupling the GC, the GC and the DAC still remain tightly coupled
- // and, in particular, the DAC needs to know how many generations the GC
- // has. However, it is not permitted to invoke virtual methods on g_pGCHeap
- // while on a DAC code path. Therefore, we need to determine the max generation
- // non-virtually, while still in a manner consistent with the interface -
- // therefore, a static field is used.
- //
- // This is not without precedent - IGCHeap::gcHeapType is a static field used
- // for a similar reason (the DAC needs to know what kind of heap it's looking at).
- inline static unsigned GetMaxGeneration()
- {
- WRAPPER_NO_CONTRACT;
-
- return IGCHeap::maxGeneration;
- }
-
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
// Returns True if software write watch is currently enabled for the GC Heap,
@@ -203,4 +197,5 @@ private:
GCHeapUtilities() = delete;
};
-#endif // _GCHEAPUTILITIES_H_ \ No newline at end of file
+#endif // _GCHEAPUTILITIES_H_
+