1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// 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.
/*
* GCCOMMON.CPP
*
* Code common to both SVR and WKS gcs
*/
#include "common.h"
#include "gcenv.h"
#include "gc.h"
#ifdef FEATURE_SVR_GC
SVAL_IMPL_INIT(uint32_t,GCHeap,gcHeapType,GCHeap::GC_HEAP_INVALID);
#endif // FEATURE_SVR_GC
GPTR_IMPL(GCHeap,g_pGCHeap);
/* global versions of the card table and brick table */
GPTR_IMPL(uint32_t,g_card_table);
/* absolute bounds of the GC memory */
GPTR_IMPL_INIT(uint8_t,g_lowest_address,0);
GPTR_IMPL_INIT(uint8_t,g_highest_address,0);
#ifdef GC_CONFIG_DRIVEN
GARY_IMPL(size_t, gc_global_mechanisms, MAX_GLOBAL_GC_MECHANISMS_COUNT);
#endif //GC_CONFIG_DRIVEN
#ifndef DACCESS_COMPILE
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
#ifdef WRITE_BARRIER_CHECK
uint8_t* g_GCShadow;
uint8_t* g_GCShadowEnd;
uint8_t* g_shadow_lowest_address = NULL;
#endif
VOLATILE(int32_t) m_GCLock = -1;
#ifdef GC_CONFIG_DRIVEN
void record_global_mechanism (int mech_index)
{
(gc_global_mechanisms[mech_index])++;
}
#endif //GC_CONFIG_DRIVEN
int32_t g_bLowMemoryFromHost = 0;
#ifdef WRITE_BARRIER_CHECK
#define INVALIDGCVALUE (void *)((size_t)0xcccccccd)
// called by the write barrier to update the shadow heap
void updateGCShadow(Object** ptr, Object* val)
{
Object** shadow = (Object**) &g_GCShadow[((uint8_t*) ptr - g_lowest_address)];
if ((uint8_t*) shadow < g_GCShadowEnd)
{
*shadow = val;
// Ensure that the write to the shadow heap occurs before the read from
// the GC heap so that race conditions are caught by INVALIDGCVALUE.
MemoryBarrier();
if(*ptr!=val)
*shadow = (Object *) INVALIDGCVALUE;
}
}
#endif // WRITE_BARRIER_CHECK
struct changed_seg
{
uint8_t * start;
uint8_t * end;
size_t gc_index;
bgc_state bgc;
changed_seg_state changed;
};
const int max_saved_changed_segs = 128;
changed_seg saved_changed_segs[max_saved_changed_segs];
int saved_changed_segs_count = 0;
void record_changed_seg (uint8_t* start, uint8_t* end,
size_t current_gc_index,
bgc_state current_bgc_state,
changed_seg_state changed_state)
{
if (saved_changed_segs_count < max_saved_changed_segs)
{
saved_changed_segs[saved_changed_segs_count].start = start;
saved_changed_segs[saved_changed_segs_count].end = end;
saved_changed_segs[saved_changed_segs_count].gc_index = current_gc_index;
saved_changed_segs[saved_changed_segs_count].bgc = current_bgc_state;
saved_changed_segs[saved_changed_segs_count].changed = changed_state;
saved_changed_segs_count++;
}
else
{
saved_changed_segs_count = 0;
}
}
#endif // !DACCESS_COMPILE
|