Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/bcutil/Cursor.hpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2001, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
/*
24
* Cursor.hpp
25
*/
26
27
#ifndef CURSOR_HPP_
28
#define CURSOR_HPP_
29
30
/* @ddr_namespace: default */
31
#include "j9comp.h"
32
#include "j9.h"
33
#include "SRPOffsetTable.hpp"
34
#include "ROMClassCreationContext.hpp"
35
36
class Cursor
37
{
38
public:
39
40
/*
41
* DataType is used to identify the type of data being written.
42
*/
43
enum DataType {
44
// Actual bytecodes
45
BYTECODE,
46
// Generic non-specific data
47
GENERIC,
48
// The romSize field of the J9ROMClass structure
49
ROM_SIZE,
50
// The size of debug information store in a ROMMethod
51
METHOD_DEBUG_SIZE,
52
// Self Relative Pointer (SRP) to non-specific data
53
SRP_TO_GENERIC,
54
// SRP to a UTF8 string
55
SRP_TO_UTF8,
56
// SRP to a Name and Signature structure
57
SRP_TO_NAME_AND_SIGNATURE,
58
// Class file bytes
59
INTERMEDIATE_CLASS_DATA,
60
// Class file bytes size
61
INTERMEDIATE_CLASS_DATA_LENGTH,
62
// SRP to a method debug data
63
SRP_TO_DEBUG_DATA,
64
// Optional flags for ROMClass
65
OPTIONAL_FLAGS,
66
// SRP to source debug extension information
67
SRP_TO_SOURCE_DEBUG_EXT,
68
// The length of source debug extension information
69
SOURCE_DEBUG_EXT_LENGTH,
70
// The source debug extension information
71
SOURCE_DEBUG_EXT_DATA,
72
// Optional file name information
73
OPTINFO_SOURCE_FILE_NAME,
74
// All the class modiers
75
ROM_CLASS_MODIFIERS,
76
// Line number data for a rom class method
77
LINE_NUMBER_DATA,
78
// Number of local variables
79
LOCAL_VARIABLE_COUNT,
80
//SRP to local variable data start
81
SRP_TO_LOCAL_VARIABLE_DATA,
82
// Local variable data
83
LOCAL_VARIABLE_DATA,
84
// Local variable data SRP to UTF8 data
85
LOCAL_VARIABLE_DATA_SRP_TO_UTF8,
86
// SRP to intermediate class data
87
SRP_TO_INTERMEDIATE_CLASS_DATA,
88
// SRP to UTF8 string for class names
89
SRP_TO_UTF8_CLASS_NAME,
90
// Class File Size
91
CLASS_FILE_SIZE
92
};
93
94
/*
95
* Mode is used to indicate the transition from one cursor type
96
* to another. This feature was specifically added to enable
97
* the comparison of ROMClass that had debug information out of line.
98
*
99
* This was required to support the ComparingCursor and ComparingCursorHelper model.
100
*/
101
enum Mode {
102
// In the mainline of the ROMClass
103
MAIN_CURSOR,
104
// Writing debug information and line number data
105
DEBUG_INFO,
106
// Writing variable information
107
VAR_INFO
108
};
109
110
Cursor(UDATA tag, SRPOffsetTable *srpOffsetTable, ROMClassCreationContext * context) :
111
_srpOffsetTable(srpOffsetTable),
112
_count(0),
113
_tag(tag),
114
_context(context),
115
/* assign -1 to be able to check if it was initialized or not */
116
_classNameIndex((U_16)-1)
117
{
118
}
119
120
virtual UDATA getCount() { return _count; }
121
122
/* Note: WritingCursor's versions of the methods below do not call these ones for
123
* performance reasons on Linux PPC (since XLC fails to inline them). If you make
124
* a change that needs to affect WritingCursor, you must change those versions too.
125
*/
126
virtual void writeU8(U_8 u8Value, DataType dataType) { _count += sizeof(U_8); }
127
virtual void writeU16(U_16 u16Value, DataType dataType) { _count += sizeof(U_16); }
128
virtual void writeU32(U_32 u32Value, DataType dataType) { _count += sizeof(U_32); }
129
virtual void writeU64(U_32 u32ValueHigh, U_32 u32ValueLow, DataType dataType) { _count += sizeof(U_64); }
130
virtual void writeUTF8(U_8* utf8Data, U_16 utf8Length, DataType dataType)
131
{
132
writeU16(utf8Length, Cursor::GENERIC);
133
writeData(utf8Data, utf8Length, Cursor::GENERIC);
134
/* Pad manually as it is significantly faster than using padToAlignment(). */
135
if (0 != (utf8Length & 1)) {
136
writeU8(0, Cursor::GENERIC);
137
}
138
}
139
virtual void writeData(U_8* bytes, UDATA length, DataType dataType) { _count += length; }
140
virtual void padToAlignment(UDATA byteAlignment, DataType dataType) {
141
/* Note: byteAlignment must be a power of 2. */
142
UDATA alignmentBits = (byteAlignment - 1);
143
UDATA adjustedCount = (_count + alignmentBits) & ~alignmentBits;
144
UDATA bytesToPad = adjustedCount - _count;
145
146
if (0 != bytesToPad) {
147
_count += bytesToPad;
148
}
149
}
150
virtual void skip(UDATA byteCount, DataType dataType = Cursor::GENERIC) { _count += byteCount; }
151
virtual U_32 peekU32() { return 0; }
152
virtual void notifyDebugDataWriteStart() { /* do nothing */ }
153
virtual void notifyVariableTableWriteEnd() { /* do nothing */ }
154
virtual void notifyDebugDataWriteEnd() { /* do nothing */ }
155
156
/*
157
* write(W)SRP will write a NULL SRP if srpKey has not been marked with mark(srpKey)
158
*/
159
virtual void writeSRP(UDATA srpKey, DataType dataType) { _count += sizeof(J9SRP); }
160
virtual void writeWSRP(UDATA srpKey, DataType dataType) { _count += sizeof(J9WSRP); }
161
virtual void mark(UDATA srpKey) { _srpOffsetTable->insert(srpKey, _count, _tag); }
162
163
#ifdef J9VM_ENV_LITTLE_ENDIAN
164
void writeBigEndianU16(U_16 u16Value, DataType dataType) { writeU16(swapU16(u16Value), dataType); }
165
#else
166
void writeBigEndianU16(U_16 u16Value, DataType dataType) { writeU16(u16Value, dataType); }
167
#endif
168
169
U_16 getClassNameIndex(void){ return _classNameIndex; }
170
void setClassNameIndex(U_16 classNameIndex){ _classNameIndex = classNameIndex; }
171
bool isSRPNull(UDATA srpKey) { return !_srpOffsetTable->isNotNull(srpKey); }
172
J9SRP computeSRP(UDATA key, J9SRP *srpAddr) { return _srpOffsetTable->computeSRP(key, srpAddr); }
173
J9WSRP computeWSRP(UDATA key, J9WSRP *wsrpAddr) { return _srpOffsetTable->computeWSRP(key, wsrpAddr); }
174
UDATA getOffsetForSRPKey(UDATA srpKey) { return _srpOffsetTable->get(srpKey); }
175
176
protected:
177
/*
178
* This functionality supports the ComparingCursor/ComparingCursorHelper model.
179
* Allowing the helpers to be re-based with a new baseAddress, which requires the
180
* count to also be reset.
181
*/
182
void resetCount() { _count = 0; }
183
184
UDATA _count;
185
ROMClassCreationContext * _context;
186
187
private:
188
#ifdef J9VM_ENV_LITTLE_ENDIAN
189
static U_16 swapU16(U_16 u16) { return ((u16 & 0xff00) >> 8) | ((u16 & 0x00ff) << 8); }
190
#endif
191
192
SRPOffsetTable *_srpOffsetTable;
193
UDATA _tag;
194
U_16 _classNameIndex;
195
};
196
197
#endif /* CURSOR_HPP_ */
198
199