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/*
7 * GCCOMMON.CPP
8 *
9 * Code common to both SVR and WKS gcs
10 */
11
12#include "common.h"
13
14#include "gcenv.h"
15#include "gc.h"
16
17IGCHeapInternal* g_theGCHeap;
18IGCHandleManager* g_theGCHandleManager;
19
20#ifdef BUILD_AS_STANDALONE
21IGCToCLR* g_theGCToCLR;
22#endif // BUILD_AS_STANDALONE
23
24#ifdef GC_CONFIG_DRIVEN
25size_t gc_global_mechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT];
26#endif //GC_CONFIG_DRIVEN
27
28#ifndef DACCESS_COMPILE
29
30#ifdef WRITE_BARRIER_CHECK
31uint8_t* g_GCShadow;
32uint8_t* g_GCShadowEnd;
33uint8_t* g_shadow_lowest_address = NULL;
34#endif
35
36uint32_t* g_gc_card_table;
37
38VOLATILE(int32_t) g_fSuspensionPending = 0;
39
40uint32_t g_yieldProcessorScalingFactor = 1;
41
42#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
43uint32_t* g_gc_card_bundle_table;
44#endif
45
46uint8_t* g_gc_lowest_address = 0;
47uint8_t* g_gc_highest_address = 0;
48GCHeapType g_gc_heap_type = GC_HEAP_INVALID;
49uint32_t g_max_generation = max_generation;
50MethodTable* g_gc_pFreeObjectMethodTable = nullptr;
51uint32_t g_num_processors = 0;
52
53#ifdef GC_CONFIG_DRIVEN
54void record_global_mechanism (int mech_index)
55{
56 (gc_global_mechanisms[mech_index])++;
57}
58#endif //GC_CONFIG_DRIVEN
59
60#ifdef WRITE_BARRIER_CHECK
61
62#define INVALIDGCVALUE (void *)((size_t)0xcccccccd)
63
64 // called by the write barrier to update the shadow heap
65void updateGCShadow(Object** ptr, Object* val)
66{
67 Object** shadow = (Object**) &g_GCShadow[((uint8_t*) ptr - g_lowest_address)];
68 if ((uint8_t*) shadow < g_GCShadowEnd)
69 {
70 *shadow = val;
71
72 // Ensure that the write to the shadow heap occurs before the read from
73 // the GC heap so that race conditions are caught by INVALIDGCVALUE.
74 MemoryBarrier();
75
76 if(*ptr!=val)
77 *shadow = (Object *) INVALIDGCVALUE;
78 }
79}
80
81#endif // WRITE_BARRIER_CHECK
82
83
84struct changed_seg
85{
86 uint8_t * start;
87 uint8_t * end;
88 size_t gc_index;
89 bgc_state bgc;
90 changed_seg_state changed;
91};
92
93
94const int max_saved_changed_segs = 128;
95
96changed_seg saved_changed_segs[max_saved_changed_segs];
97int saved_changed_segs_count = 0;
98
99void record_changed_seg (uint8_t* start, uint8_t* end,
100 size_t current_gc_index,
101 bgc_state current_bgc_state,
102 changed_seg_state changed_state)
103{
104 if (saved_changed_segs_count < max_saved_changed_segs)
105 {
106 saved_changed_segs[saved_changed_segs_count].start = start;
107 saved_changed_segs[saved_changed_segs_count].end = end;
108 saved_changed_segs[saved_changed_segs_count].gc_index = current_gc_index;
109 saved_changed_segs[saved_changed_segs_count].bgc = current_bgc_state;
110 saved_changed_segs[saved_changed_segs_count].changed = changed_state;
111 saved_changed_segs_count++;
112 }
113 else
114 {
115 saved_changed_segs_count = 0;
116 }
117}
118
119#endif // !DACCESS_COMPILE
120