Mon, 12 Aug 2019 18:30:40 +0300
8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens
1 /*
2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_OOPS_FIELDINFO_HPP
26 #define SHARE_VM_OOPS_FIELDINFO_HPP
28 #include "oops/constantPool.hpp"
29 #include "oops/typeArrayOop.hpp"
30 #include "classfile/vmSymbols.hpp"
32 // This class represents the field information contained in the fields
33 // array of an InstanceKlass. Currently it's laid on top an array of
34 // Java shorts but in the future it could simply be used as a real
35 // array type. FieldInfo generally shouldn't be used directly.
36 // Fields should be queried either through InstanceKlass or through
37 // the various FieldStreams.
38 class FieldInfo VALUE_OBJ_CLASS_SPEC {
39 friend class fieldDescriptor;
40 friend class JavaFieldStream;
41 friend class ClassFileParser;
43 public:
44 // fields
45 // Field info extracted from the class file and stored
46 // as an array of 6 shorts.
48 #define FIELDINFO_TAG_SIZE 2
49 #define FIELDINFO_TAG_BLANK 0
50 #define FIELDINFO_TAG_OFFSET 1
51 #define FIELDINFO_TAG_TYPE_PLAIN 2
52 #define FIELDINFO_TAG_TYPE_CONTENDED 3
53 #define FIELDINFO_TAG_MASK 3
55 // Packed field has the tag, and can be either of:
56 // hi bits <--------------------------- lo bits
57 // |---------high---------|---------low---------|
58 // ..........................................00 - blank
59 // [------------------offset----------------]01 - real field offset
60 // ......................[-------type-------]10 - plain field with type
61 // [--contention_group--][-------type-------]11 - contended field with type and contention group
62 enum FieldOffset {
63 access_flags_offset = 0,
64 name_index_offset = 1,
65 signature_index_offset = 2,
66 initval_index_offset = 3,
67 low_packed_offset = 4,
68 high_packed_offset = 5,
69 field_slots = 6
70 };
72 private:
73 u2 _shorts[field_slots];
75 void set_name_index(u2 val) { _shorts[name_index_offset] = val; }
76 void set_signature_index(u2 val) { _shorts[signature_index_offset] = val; }
77 void set_initval_index(u2 val) { _shorts[initval_index_offset] = val; }
79 u2 name_index() const { return _shorts[name_index_offset]; }
80 u2 signature_index() const { return _shorts[signature_index_offset]; }
81 u2 initval_index() const { return _shorts[initval_index_offset]; }
83 public:
84 static FieldInfo* from_field_array(Array<u2>* fields, int index) {
85 return ((FieldInfo*)fields->adr_at(index * field_slots));
86 }
87 static FieldInfo* from_field_array(u2* fields, int index) {
88 return ((FieldInfo*)(fields + index * field_slots));
89 }
91 void initialize(u2 access_flags,
92 u2 name_index,
93 u2 signature_index,
94 u2 initval_index) {
95 _shorts[access_flags_offset] = access_flags;
96 _shorts[name_index_offset] = name_index;
97 _shorts[signature_index_offset] = signature_index;
98 _shorts[initval_index_offset] = initval_index;
99 _shorts[low_packed_offset] = 0;
100 _shorts[high_packed_offset] = 0;
101 }
103 u2 access_flags() const { return _shorts[access_flags_offset]; }
104 u4 offset() const {
105 u2 lo = _shorts[low_packed_offset];
106 switch(lo & FIELDINFO_TAG_MASK) {
107 case FIELDINFO_TAG_OFFSET:
108 return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
109 #ifndef PRODUCT
110 case FIELDINFO_TAG_TYPE_PLAIN:
111 fatal("Asking offset for the plain type field");
112 case FIELDINFO_TAG_TYPE_CONTENDED:
113 fatal("Asking offset for the contended type field");
114 case FIELDINFO_TAG_BLANK:
115 fatal("Asking offset for the blank field");
116 #endif
117 }
118 ShouldNotReachHere();
119 return 0;
120 }
122 bool is_contended() const {
123 u2 lo = _shorts[low_packed_offset];
124 switch(lo & FIELDINFO_TAG_MASK) {
125 case FIELDINFO_TAG_TYPE_PLAIN:
126 return false;
127 case FIELDINFO_TAG_TYPE_CONTENDED:
128 return true;
129 #ifndef PRODUCT
130 case FIELDINFO_TAG_OFFSET:
131 fatal("Asking contended flag for the field with offset");
132 case FIELDINFO_TAG_BLANK:
133 fatal("Asking contended flag for the blank field");
134 #endif
135 }
136 ShouldNotReachHere();
137 return false;
138 }
140 u2 contended_group() const {
141 u2 lo = _shorts[low_packed_offset];
142 switch(lo & FIELDINFO_TAG_MASK) {
143 case FIELDINFO_TAG_TYPE_PLAIN:
144 return 0;
145 case FIELDINFO_TAG_TYPE_CONTENDED:
146 return _shorts[high_packed_offset];
147 #ifndef PRODUCT
148 case FIELDINFO_TAG_OFFSET:
149 fatal("Asking the contended group for the field with offset");
150 case FIELDINFO_TAG_BLANK:
151 fatal("Asking the contended group for the blank field");
152 #endif
153 }
154 ShouldNotReachHere();
155 return 0;
156 }
158 u2 allocation_type() const {
159 u2 lo = _shorts[low_packed_offset];
160 switch(lo & FIELDINFO_TAG_MASK) {
161 case FIELDINFO_TAG_TYPE_PLAIN:
162 case FIELDINFO_TAG_TYPE_CONTENDED:
163 return (lo >> FIELDINFO_TAG_SIZE);
164 #ifndef PRODUCT
165 case FIELDINFO_TAG_OFFSET:
166 fatal("Asking the field type for field with offset");
167 case FIELDINFO_TAG_BLANK:
168 fatal("Asking the field type for the blank field");
169 #endif
170 }
171 ShouldNotReachHere();
172 return 0;
173 }
175 bool is_offset_set() const {
176 return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET;
177 }
179 Symbol* name(constantPoolHandle cp) const {
180 int index = name_index();
181 if (is_internal()) {
182 return lookup_symbol(index);
183 }
184 return cp->symbol_at(index);
185 }
187 Symbol* signature(constantPoolHandle cp) const {
188 int index = signature_index();
189 if (is_internal()) {
190 return lookup_symbol(index);
191 }
192 return cp->symbol_at(index);
193 }
195 void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
196 void set_offset(u4 val) {
197 val = val << FIELDINFO_TAG_SIZE; // make room for tag
198 _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET;
199 _shorts[high_packed_offset] = extract_high_short_from_int(val);
200 }
202 void set_allocation_type(int type) {
203 u2 lo = _shorts[low_packed_offset];
204 switch(lo & FIELDINFO_TAG_MASK) {
205 case FIELDINFO_TAG_BLANK:
206 _shorts[low_packed_offset] = ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF;
207 _shorts[low_packed_offset] &= ~FIELDINFO_TAG_MASK;
208 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN;
209 return;
210 #ifndef PRODUCT
211 case FIELDINFO_TAG_TYPE_PLAIN:
212 case FIELDINFO_TAG_TYPE_CONTENDED:
213 case FIELDINFO_TAG_OFFSET:
214 fatal("Setting the field type with overwriting");
215 #endif
216 }
217 ShouldNotReachHere();
218 }
220 void set_contended_group(u2 val) {
221 u2 lo = _shorts[low_packed_offset];
222 switch(lo & FIELDINFO_TAG_MASK) {
223 case FIELDINFO_TAG_TYPE_PLAIN:
224 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED;
225 _shorts[high_packed_offset] = val;
226 return;
227 #ifndef PRODUCT
228 case FIELDINFO_TAG_TYPE_CONTENDED:
229 fatal("Overwriting contended group");
230 case FIELDINFO_TAG_BLANK:
231 fatal("Setting contended group for the blank field");
232 case FIELDINFO_TAG_OFFSET:
233 fatal("Setting contended group for field with offset");
234 #endif
235 }
236 ShouldNotReachHere();
237 }
239 bool is_internal() const {
240 return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0;
241 }
243 bool is_stable() const {
244 return (access_flags() & JVM_ACC_FIELD_STABLE) != 0;
245 }
246 void set_stable(bool z) {
247 if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE;
248 else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE;
249 }
251 Symbol* lookup_symbol(int symbol_index) const {
252 assert(is_internal(), "only internal fields");
253 return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
254 }
255 };
257 #endif // SHARE_VM_OOPS_FIELDINFO_HPP