1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*
6 * gcload.cpp
7 *
8 * Code for loading and initializing the GC. The code in this file
9 * is used in the startup path of both a standalone and non-standalone GC.
10 */
11
12#include "common.h"
13#include "gcenv.h"
14#include "gc.h"
15
16#ifdef _MSC_VER
17#define DLLEXPORT __declspec(dllexport)
18#else
19#define DLLEXPORT __attribute__ ((visibility ("default")))
20#endif // _MSC_VER
21
22#define GC_EXPORT extern "C" DLLEXPORT
23
24// These symbols are defined in gc.cpp and populate the GcDacVars
25// structure with the addresses of DAC variables within the GC.
26namespace WKS
27{
28 extern void PopulateDacVars(GcDacVars* dacVars);
29}
30
31namespace SVR
32{
33 extern void PopulateDacVars(GcDacVars* dacVars);
34}
35
36// This symbol populates GcDacVars with handle table dacvars.
37extern void PopulateHandleTableDacVars(GcDacVars* dacVars);
38
39GC_EXPORT
40void
41GC_VersionInfo(/* Out */ VersionInfo* info)
42{
43 info->MajorVersion = GC_INTERFACE_MAJOR_VERSION;
44 info->MinorVersion = GC_INTERFACE_MINOR_VERSION;
45 info->BuildVersion = 0;
46 info->Name = "CoreCLR GC";
47}
48
49GC_EXPORT
50HRESULT
51GC_Initialize(
52 /* In */ IGCToCLR* clrToGC,
53 /* Out */ IGCHeap** gcHeap,
54 /* Out */ IGCHandleManager** gcHandleManager,
55 /* Out */ GcDacVars* gcDacVars
56)
57{
58 IGCHeapInternal* heap;
59
60 assert(gcDacVars != nullptr);
61 assert(gcHeap != nullptr);
62 assert(gcHandleManager != nullptr);
63
64#ifdef BUILD_AS_STANDALONE
65 assert(clrToGC != nullptr);
66 g_theGCToCLR = clrToGC;
67#else
68 UNREFERENCED_PARAMETER(clrToGC);
69 assert(clrToGC == nullptr);
70#endif
71
72 // Initialize GCConfig before anything else - initialization of our
73 // various components may want to query the current configuration.
74 GCConfig::Initialize();
75
76 if (!GCToOSInterface::Initialize())
77 {
78 return E_FAIL;
79 }
80
81 IGCHandleManager* handleManager = CreateGCHandleManager();
82 if (handleManager == nullptr)
83 {
84 return E_OUTOFMEMORY;
85 }
86
87#ifdef FEATURE_SVR_GC
88 if (GCConfig::GetServerGC())
89 {
90#ifdef WRITE_BARRIER_CHECK
91 g_GCShadow = 0;
92 g_GCShadowEnd = 0;
93#endif // WRITE_BARRIER_CHECK
94
95 g_gc_heap_type = GC_HEAP_SVR;
96 heap = SVR::CreateGCHeap();
97 SVR::PopulateDacVars(gcDacVars);
98 }
99 else
100 {
101 g_gc_heap_type = GC_HEAP_WKS;
102 heap = WKS::CreateGCHeap();
103 WKS::PopulateDacVars(gcDacVars);
104 }
105#else
106 g_gc_heap_type = GC_HEAP_WKS;
107 heap = WKS::CreateGCHeap();
108 WKS::PopulateDacVars(gcDacVars);
109#endif
110
111 PopulateHandleTableDacVars(gcDacVars);
112 if (heap == nullptr)
113 {
114 return E_OUTOFMEMORY;
115 }
116
117 g_theGCHeap = heap;
118 *gcHandleManager = handleManager;
119 *gcHeap = heap;
120 return S_OK;
121}
122