blob: 5e83b67002f3cd6da527e6275dec201c875d7803 (
plain)
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
116
|
// 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.
//
// Implementations of methods of OptionalFields which are used only at runtime (i.e. reading field values).
//
#include "common.h"
#ifndef RHDUMP
#include "CommonTypes.h"
#include "CommonMacros.h"
#include "daccess.h"
#include "PalRedhawkCommon.h"
#include "PalRedhawk.h"
#include "rhassert.h"
#include "rhbinder.h"
#include "eetype.h"
#include "ObjectLayout.h"
#include "varint.h"
#endif
// Reads the field type from the current byte of the stream and indicates whether this represents the last
// field.
/*static*/ OptionalFieldTag OptionalFields::DecodeFieldTag(PTR_UInt8 * ppFields, bool *pfLastField)
{
UInt8 tagByte;
tagByte = **ppFields;
// The last field has the most significant bit of the byte set.
*pfLastField = (tagByte & 0x80) != 0;
// The remaining 7 bits encode the field type.
OptionalFieldTag eTag = (OptionalFieldTag)(tagByte & 0x7f);
// Advance the pointer past the header.
(*ppFields)++;
return eTag;
}
// Reads a field value (or the basis for an out-of-line record delta) starting from the first byte after the
// field header. Advances the field location to the start of the next field.
UInt32 OptionalFields::DecodeFieldValue(PTR_UInt8 * ppFields)
{
// VarInt is used to encode the field value (and updates the field pointer in doing so).
return VarInt::ReadUnsigned(*ppFields);
}
/*static*/ UInt32 OptionalFields::GetInlineField(OptionalFieldTag eTag, UInt32 uiDefaultValue)
{
// Point at start of encoding stream.
PTR_UInt8 pFields = dac_cast<PTR_UInt8>(this);
for (;;)
{
// Read field tag, an indication of whether this is the last field and the field value (we always read
// the value, even if the tag is not a match because decoding the value advances the field pointer to
// the next field).
bool fLastField;
OptionalFieldTag eCurrentTag = DecodeFieldTag(&pFields, &fLastField);
UInt32 uiCurrentValue = DecodeFieldValue(&pFields);
// If we found a tag match return the current value.
if (eCurrentTag == eTag)
return uiCurrentValue;
// If this was the last field we're done as well.
if (fLastField)
break;
}
// Reached end of stream without getting a match. Field is not present so return default value.
return uiDefaultValue;
}
#if 0
// Currently not used for ProjectN, implementation needs to be "DAC'ified" if needed again
void * OptionalFields::GetOutlineField(OptionalFieldTag eTag, size_t cbValueAlignment)
{
// Point at start of encoding stream.
UInt8 * pFields = (UInt8*)this;
for (;;)
{
// Read field tag, an indication of whether this is the last field and the field value (we always read
// the value, even if the tag is not a match because decoding the value advances the field pointer to
// the next field).
bool fLastField;
OptionalFieldTag eCurrentTag = DecodeFieldTag(&pFields, &fLastField);
UInt32 uiCurrentValue = DecodeFieldValue(&pFields);
// If we found a tag match then we need to compute the out-of-line record address to return.
if (eCurrentTag == eTag)
{
// Scale the value (actually a delta from the base address) based on the alignment of the target
// record.
uiCurrentValue *= (UInt32)cbValueAlignment;
// Locate the address where the base address is stored. They are stored periodically at aligned
// addresses relative to OptionalFields records. We can locate them by masking off bits from the
// least significant portion of this records address.
UInt8 ** pBaseAddress = (UInt8**)((size_t)this & ~(size_t)OFC_HeaderAlignmentMask);
return *pBaseAddress + uiCurrentValue;
}
// If this was the last field we're done as well.
if (fLastField)
break;
}
// Reached end of stream without getting a match. Field is not present so return NULL.
return NULL;
}
#endif
|