Bug Summary

File:jdk/src/hotspot/share/classfile/stackMapTable.hpp
Warning:line 100, column 33
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name stackMapTable.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/classfile/stackMapTable.cpp

/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/stackMapTable.cpp

1/*
2 * Copyright (c) 2003, 2020, 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 */
24
25#include "precompiled.hpp"
26#include "classfile/stackMapTable.hpp"
27#include "classfile/verifier.hpp"
28#include "memory/resourceArea.hpp"
29#include "oops/constantPool.hpp"
30#include "oops/oop.inline.hpp"
31#include "runtime/handles.inline.hpp"
32
33StackMapTable::StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,
34 u2 max_locals, u2 max_stack,
35 char* code_data, int code_len, TRAPSJavaThread* __the_thread__) {
36 _code_length = code_len;
37 _frame_count = reader->get_frame_count();
38 if (_frame_count > 0) {
39 _frame_array = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,(StackMapFrame**) resource_allocate_bytes(__the_thread__, (_frame_count
) * sizeof(StackMapFrame*))
40 StackMapFrame*, _frame_count)(StackMapFrame**) resource_allocate_bytes(__the_thread__, (_frame_count
) * sizeof(StackMapFrame*))
;
41 StackMapFrame* pre_frame = init_frame;
42 for (int32_t i = 0; i < _frame_count; i++) {
43 StackMapFrame* frame = reader->next(
44 pre_frame, i == 0, max_locals, max_stack,
45 CHECK_VERIFY(pre_frame->verifier())__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0); if ((pre_frame->verifier())->has_error
()) return; ((void)0
);
46 _frame_array[i] = frame;
47 int offset = frame->offset();
48 if (offset >= code_len || code_data[offset] == 0) {
49 frame->verifier()->verify_error(
50 ErrorContext::bad_stackmap(i, frame),
51 "StackMapTable error: bad offset");
52 return;
53 }
54 pre_frame = frame;
55 }
56 }
57 reader->check_end(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
58}
59
60// This method is only called by method in StackMapTable.
61int StackMapTable::get_index_from_offset(int32_t offset) const {
62 int i = 0;
63 for (; i < _frame_count; i++) {
64 if (_frame_array[i]->offset() == offset) {
65 return i;
66 }
67 }
68 return i; // frame with offset doesn't exist in the array
69}
70
71bool StackMapTable::match_stackmap(
72 StackMapFrame* frame, int32_t target,
73 bool match, bool update, ErrorContext* ctx, TRAPSJavaThread* __the_thread__) const {
74 int index = get_index_from_offset(target);
75 return match_stackmap(frame, target, index, match, update, ctx, THREAD__the_thread__);
76}
77
78// Match and/or update current_frame to the frame in stackmap table with
79// specified offset and frame index. Return true if the two frames match.
80//
81// The values of match and update are: _match__update
82//
83// checking a branch target: true false
84// checking an exception handler: true false
85// linear bytecode verification following an
86// unconditional branch: false true
87// linear bytecode verification not following an
88// unconditional branch: true true
89bool StackMapTable::match_stackmap(
90 StackMapFrame* frame, int32_t target, int32_t frame_index,
91 bool match, bool update, ErrorContext* ctx, TRAPSJavaThread* __the_thread__) const {
92 if (frame_index < 0 || frame_index >= _frame_count) {
93 *ctx = ErrorContext::missing_stackmap(frame->offset());
94 frame->verifier()->verify_error(
95 *ctx, "Expecting a stackmap frame at branch target %d", target);
96 return false;
97 }
98
99 StackMapFrame *stackmap_frame = _frame_array[frame_index];
100 bool result = true;
101 if (match) {
102 // Has direct control flow from last instruction, need to match the two
103 // frames.
104 result = frame->is_assignable_to(stackmap_frame,
105 ctx, CHECK_VERIFY_(frame->verifier(), result)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return result; (void)(0); if ((frame->verifier())->
has_error()) return (result); ((void)0
);
106 }
107 if (update) {
108 // Use the frame in stackmap table as current frame
109 int lsize = stackmap_frame->locals_size();
110 int ssize = stackmap_frame->stack_size();
111 if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
112 // Make sure unused type array items are all _bogus_type.
113 frame->reset();
114 }
115 frame->set_locals_size(lsize);
116 frame->copy_locals(stackmap_frame);
117 frame->set_stack_size(ssize);
118 frame->copy_stack(stackmap_frame);
119 frame->set_flags(stackmap_frame->flags());
120 }
121 return result;
122}
123
124void StackMapTable::check_jump_target(
125 StackMapFrame* frame, int32_t target, TRAPSJavaThread* __the_thread__) const {
126 ErrorContext ctx;
127 bool match = match_stackmap(
128 frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0); if ((frame->verifier())->has_error
()) return; ((void)0
);
129 if (!match || (target < 0 || target >= _code_length)) {
130 frame->verifier()->verify_error(ctx,
131 "Inconsistent stackmap frames at branch target %d", target);
132 }
133}
134
135void StackMapTable::print_on(outputStream* str) const {
136 str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
137 str->indent().print_cr("table = { ");
138 {
139 streamIndentor si(str);
140 for (int32_t i = 0; i < _frame_count; ++i) {
141 _frame_array[i]->print_on(str);
142 }
143 }
144 str->print_cr(" }");
145}
146
147StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,
148 int32_t code_len, TRAPSJavaThread* __the_thread__) :
149 _verifier(v), _stream(stream),
150 _code_data(code_data), _code_length(code_len) {
151 methodHandle m = v->method();
152 if (m->has_stackmap_table()) {
1
Taking true branch
153 _cp = constantPoolHandle(THREAD__the_thread__, m->constants());
154 _frame_count = _stream->get_u2(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
2
Calling 'StackMapStream::get_u2'
155 } else {
156 // There's no stackmap table present. Frame count and size are 0.
157 _frame_count = 0;
158 }
159}
160
161int32_t StackMapReader::chop(
162 VerificationType* locals, int32_t length, int32_t chops) {
163 if (locals == NULL__null) return -1;
164 int32_t pos = length - 1;
165 for (int32_t i=0; i<chops; i++) {
166 if (locals[pos].is_category2_2nd()) {
167 pos -= 2;
168 } else {
169 pos --;
170 }
171 if (pos<0 && i<(chops-1)) return -1;
172 }
173 return pos+1;
174}
175
176VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPSJavaThread* __the_thread__) {
177 u1 tag = _stream->get_u1(THREAD__the_thread__);
178 if (tag < (u1)ITEM_UninitializedThis) {
179 return VerificationType::from_tag(tag);
180 }
181 if (tag == ITEM_Object) {
182 u2 class_index = _stream->get_u2(THREAD__the_thread__);
183 int nconstants = _cp->length();
184 if ((class_index <= 0 || class_index >= nconstants) ||
185 (!_cp->tag_at(class_index).is_klass() &&
186 !_cp->tag_at(class_index).is_unresolved_klass())) {
187 _stream->stackmap_format_error("bad class index", THREAD__the_thread__);
188 return VerificationType::bogus_type();
189 }
190 return VerificationType::reference_type(_cp->klass_name_at(class_index));
191 }
192 if (tag == ITEM_UninitializedThis) {
193 if (flags != NULL__null) {
194 *flags |= FLAG_THIS_UNINIT;
195 }
196 return VerificationType::uninitialized_this_type();
197 }
198 if (tag == ITEM_Uninitialized) {
199 u2 offset = _stream->get_u2(THREAD__the_thread__);
200 if (offset >= _code_length ||
201 _code_data[offset] != ClassVerifier::NEW_OFFSET) {
202 _verifier->class_format_error(
203 "StackMapTable format error: bad offset for Uninitialized");
204 return VerificationType::bogus_type();
205 }
206 return VerificationType::uninitialized_type(offset);
207 }
208 _stream->stackmap_format_error("bad verification type", THREAD__the_thread__);
209 return VerificationType::bogus_type();
210}
211
212StackMapFrame* StackMapReader::next(
213 StackMapFrame* pre_frame, bool first, u2 max_locals, u2 max_stack, TRAPSJavaThread* __the_thread__) {
214 StackMapFrame* frame;
215 int offset;
216 VerificationType* locals = NULL__null;
217 u1 frame_type = _stream->get_u1(THREAD__the_thread__);
218 if (frame_type < 64) {
219 // same_frame
220 if (first) {
221 offset = frame_type;
222 // Can't share the locals array since that is updated by the verifier.
223 if (pre_frame->locals_size() > 0) {
224 locals = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
225 THREAD, VerificationType, pre_frame->locals_size())(VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
;
226 }
227 } else {
228 offset = pre_frame->offset() + frame_type + 1;
229 locals = pre_frame->locals();
230 }
231 frame = new StackMapFrame(
232 offset, pre_frame->flags(), pre_frame->locals_size(), 0,
233 max_locals, max_stack, locals, NULL__null, _verifier);
234 if (first && locals != NULL__null) {
235 frame->copy_locals(pre_frame);
236 }
237 return frame;
238 }
239 if (frame_type < 128) {
240 // same_locals_1_stack_item_frame
241 if (first) {
242 offset = frame_type - 64;
243 // Can't share the locals array since that is updated by the verifier.
244 if (pre_frame->locals_size() > 0) {
245 locals = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
246 THREAD, VerificationType, pre_frame->locals_size())(VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
;
247 }
248 } else {
249 offset = pre_frame->offset() + frame_type - 63;
250 locals = pre_frame->locals();
251 }
252 VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
2) * sizeof(VerificationType))
253 THREAD, VerificationType, 2)(VerificationType*) resource_allocate_bytes(__the_thread__, (
2) * sizeof(VerificationType))
;
254 u2 stack_size = 1;
255 stack[0] = parse_verification_type(NULL__null, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
256 if (stack[0].is_category2()) {
257 stack[1] = stack[0].to_category2_2nd();
258 stack_size = 2;
259 }
260 check_verification_type_array_size(
261 stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
262 frame = new StackMapFrame(
263 offset, pre_frame->flags(), pre_frame->locals_size(), stack_size,
264 max_locals, max_stack, locals, stack, _verifier);
265 if (first && locals != NULL__null) {
266 frame->copy_locals(pre_frame);
267 }
268 return frame;
269 }
270
271 u2 offset_delta = _stream->get_u2(THREAD__the_thread__);
272
273 if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
274 // reserved frame types
275 _stream->stackmap_format_error(
276 "reserved frame type", CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
277 }
278
279 if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
280 // same_locals_1_stack_item_frame_extended
281 if (first) {
282 offset = offset_delta;
283 // Can't share the locals array since that is updated by the verifier.
284 if (pre_frame->locals_size() > 0) {
285 locals = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
286 THREAD, VerificationType, pre_frame->locals_size())(VerificationType*) resource_allocate_bytes(__the_thread__, (
pre_frame->locals_size()) * sizeof(VerificationType))
;
287 }
288 } else {
289 offset = pre_frame->offset() + offset_delta + 1;
290 locals = pre_frame->locals();
291 }
292 VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
2) * sizeof(VerificationType))
293 THREAD, VerificationType, 2)(VerificationType*) resource_allocate_bytes(__the_thread__, (
2) * sizeof(VerificationType))
;
294 u2 stack_size = 1;
295 stack[0] = parse_verification_type(NULL__null, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
296 if (stack[0].is_category2()) {
297 stack[1] = stack[0].to_category2_2nd();
298 stack_size = 2;
299 }
300 check_verification_type_array_size(
301 stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
302 frame = new StackMapFrame(
303 offset, pre_frame->flags(), pre_frame->locals_size(), stack_size,
304 max_locals, max_stack, locals, stack, _verifier);
305 if (first && locals != NULL__null) {
306 frame->copy_locals(pre_frame);
307 }
308 return frame;
309 }
310
311 if (frame_type <= SAME_EXTENDED) {
312 // chop_frame or same_frame_extended
313 locals = pre_frame->locals();
314 int length = pre_frame->locals_size();
315 int chops = SAME_EXTENDED - frame_type;
316 int new_length = length;
317 u1 flags = pre_frame->flags();
318 if (chops != 0) {
319 new_length = chop(locals, length, chops);
320 check_verification_type_array_size(
321 new_length, max_locals, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
322 // Recompute flags since uninitializedThis could have been chopped.
323 flags = 0;
324 for (int i=0; i<new_length; i++) {
325 if (locals[i].is_uninitialized_this()) {
326 flags |= FLAG_THIS_UNINIT;
327 break;
328 }
329 }
330 }
331 if (first) {
332 offset = offset_delta;
333 // Can't share the locals array since that is updated by the verifier.
334 if (new_length > 0) {
335 locals = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
new_length) * sizeof(VerificationType))
336 THREAD, VerificationType, new_length)(VerificationType*) resource_allocate_bytes(__the_thread__, (
new_length) * sizeof(VerificationType))
;
337 } else {
338 locals = NULL__null;
339 }
340 } else {
341 offset = pre_frame->offset() + offset_delta + 1;
342 }
343 frame = new StackMapFrame(
344 offset, flags, new_length, 0, max_locals, max_stack,
345 locals, NULL__null, _verifier);
346 if (first && locals != NULL__null) {
347 frame->copy_locals(pre_frame);
348 }
349 return frame;
350 } else if (frame_type < SAME_EXTENDED + 4) {
351 // append_frame
352 int appends = frame_type - SAME_EXTENDED;
353 int real_length = pre_frame->locals_size();
354 int new_length = real_length + appends*2;
355 locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length)(VerificationType*) resource_allocate_bytes(__the_thread__, (
new_length) * sizeof(VerificationType))
;
356 VerificationType* pre_locals = pre_frame->locals();
357 int i;
358 for (i=0; i<pre_frame->locals_size(); i++) {
359 locals[i] = pre_locals[i];
360 }
361 u1 flags = pre_frame->flags();
362 for (i=0; i<appends; i++) {
363 locals[real_length] = parse_verification_type(&flags, THREAD__the_thread__);
364 if (locals[real_length].is_category2()) {
365 locals[real_length + 1] = locals[real_length].to_category2_2nd();
366 ++real_length;
367 }
368 ++real_length;
369 }
370 check_verification_type_array_size(
371 real_length, max_locals, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
372 if (first) {
373 offset = offset_delta;
374 } else {
375 offset = pre_frame->offset() + offset_delta + 1;
376 }
377 frame = new StackMapFrame(
378 offset, flags, real_length, 0, max_locals,
379 max_stack, locals, NULL__null, _verifier);
380 return frame;
381 }
382 if (frame_type == FULL) {
383 // full_frame
384 u1 flags = 0;
385 u2 locals_size = _stream->get_u2(THREAD__the_thread__);
386 int real_locals_size = 0;
387 if (locals_size > 0) {
388 locals = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
locals_size*2) * sizeof(VerificationType))
389 THREAD, VerificationType, locals_size*2)(VerificationType*) resource_allocate_bytes(__the_thread__, (
locals_size*2) * sizeof(VerificationType))
;
390 }
391 int i;
392 for (i=0; i<locals_size; i++) {
393 locals[real_locals_size] = parse_verification_type(&flags, THREAD__the_thread__);
394 if (locals[real_locals_size].is_category2()) {
395 locals[real_locals_size + 1] =
396 locals[real_locals_size].to_category2_2nd();
397 ++real_locals_size;
398 }
399 ++real_locals_size;
400 }
401 check_verification_type_array_size(
402 real_locals_size, max_locals, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
403 u2 stack_size = _stream->get_u2(THREAD__the_thread__);
404 int real_stack_size = 0;
405 VerificationType* stack = NULL__null;
406 if (stack_size > 0) {
407 stack = NEW_RESOURCE_ARRAY_IN_THREAD((VerificationType*) resource_allocate_bytes(__the_thread__, (
stack_size*2) * sizeof(VerificationType))
408 THREAD, VerificationType, stack_size*2)(VerificationType*) resource_allocate_bytes(__the_thread__, (
stack_size*2) * sizeof(VerificationType))
;
409 }
410 for (i=0; i<stack_size; i++) {
411 stack[real_stack_size] = parse_verification_type(NULL__null, THREAD__the_thread__);
412 if (stack[real_stack_size].is_category2()) {
413 stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
414 ++real_stack_size;
415 }
416 ++real_stack_size;
417 }
418 check_verification_type_array_size(
419 real_stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((_verifier)->has_error(
)) return (__null); ((void)0
);
420 if (first) {
421 offset = offset_delta;
422 } else {
423 offset = pre_frame->offset() + offset_delta + 1;
424 }
425 frame = new StackMapFrame(
426 offset, flags, real_locals_size, real_stack_size,
427 max_locals, max_stack, locals, stack, _verifier);
428 return frame;
429 }
430
431 _stream->stackmap_format_error(
432 "reserved frame type", CHECK_VERIFY_(pre_frame->verifier(), NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0); if ((pre_frame->verifier())
->has_error()) return (__null); ((void)0
);
433 return NULL__null;
434}

/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/stackMapTable.hpp

1/*
2 * Copyright (c) 2003, 2019, 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 */
24
25#ifndef SHARE_CLASSFILE_STACKMAPTABLE_HPP
26#define SHARE_CLASSFILE_STACKMAPTABLE_HPP
27
28#include "classfile/stackMapFrame.hpp"
29#include "classfile/verifier.hpp"
30#include "memory/allocation.hpp"
31#include "oops/constantPool.hpp"
32#include "oops/method.hpp"
33#include "utilities/bytes.hpp"
34#include "utilities/globalDefinitions.hpp"
35
36class StackMapReader;
37
38// StackMapTable class is the StackMap table used by type checker
39class StackMapTable : public StackObj {
40 private:
41 // Logically, the _frame_count (as well as many fields in the StackFrame)
42 // should be a u2, but if we defined the variable as that type it will
43 // be difficult to detect/recover from overflow or underflow conditions.
44 // Widening the type and making it signed will help detect these.
45 int32_t _code_length;
46 int32_t _frame_count; // Stackmap frame count
47 StackMapFrame** _frame_array;
48
49 public:
50 StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,
51 u2 max_locals, u2 max_stack,
52 char* code_data, int code_len, TRAPSJavaThread* __the_thread__);
53
54 inline int32_t get_frame_count() const { return _frame_count; }
55 inline int get_offset(int index) const {
56 return _frame_array[index]->offset();
57 }
58
59 // Match and/or update current_frame to the frame in stackmap table with
60 // specified offset. Return true if the two frames match.
61 bool match_stackmap(
62 StackMapFrame* current_frame, int32_t offset,
63 bool match, bool update, ErrorContext* ctx, TRAPSJavaThread* __the_thread__) const;
64 // Match and/or update current_frame to the frame in stackmap table with
65 // specified offset and frame index. Return true if the two frames match.
66 bool match_stackmap(
67 StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
68 bool match, bool update, ErrorContext* ctx, TRAPSJavaThread* __the_thread__) const;
69
70 // Check jump instructions. Make sure there are no uninitialized
71 // instances on backward branch.
72 void check_jump_target(StackMapFrame* frame, int32_t target, TRAPSJavaThread* __the_thread__) const;
73
74 // The following methods are only used inside this class.
75
76 // Returns the frame array index where the frame with offset is stored.
77 int get_index_from_offset(int32_t offset) const;
78
79 void print_on(outputStream* str) const;
80};
81
82class StackMapStream : StackObj {
83 private:
84 Array<u1>* _data;
85 int _index;
86 public:
87 StackMapStream(Array<u1>* ah)
88 : _data(ah), _index(0) {
89 }
90 u1 get_u1(TRAPSJavaThread* __the_thread__) {
91 if (_data == NULL__null || _index >= _data->length()) {
92 stackmap_format_error("access beyond the end of attribute", CHECK_0__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return 0; (void)(0
);
93 }
94 return _data->at(_index++);
95 }
96 u2 get_u2(TRAPSJavaThread* __the_thread__) {
97 if (_data == NULL__null || _index >= _data->length() - 1) {
3
Assuming field '_data' is equal to NULL
98 stackmap_format_error("access beyond the end of attribute", CHECK_0__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return 0; (void)(0
);
4
Calling 'ThreadShadow::has_pending_exception'
10
Returning from 'ThreadShadow::has_pending_exception'
11
Taking false branch
99 }
100 u2 res = Bytes::get_Java_u2(_data->adr_at(_index));
12
Called C++ object pointer is null
101 _index += 2;
102 return res;
103 }
104 bool at_end() {
105 return (_data == NULL__null) || (_index == _data->length());
106 }
107 static void stackmap_format_error(const char* msg, TRAPSJavaThread* __the_thread__);
108};
109
110class StackMapReader : StackObj {
111 private:
112 // information about the class and method
113 constantPoolHandle _cp;
114 ClassVerifier* _verifier;
115 StackMapStream* _stream;
116 char* _code_data;
117 int32_t _code_length;
118
119 // information get from the attribute
120 int32_t _frame_count; // frame count
121
122 int32_t chop(VerificationType* locals, int32_t length, int32_t chops);
123 VerificationType parse_verification_type(u1* flags, TRAPSJavaThread* __the_thread__);
124 void check_verification_type_array_size(
125 int32_t size, int32_t max_size, TRAPSJavaThread* __the_thread__) {
126 if (size < 0 || size > max_size) {
127 // Since this error could be caused someone rewriting the method
128 // but not knowing to update the stackmap data, we call the the
129 // verifier's error method, which may not throw an exception and
130 // failover to the old verifier instead.
131 _verifier->class_format_error(
132 "StackMapTable format error: bad type array size");
133 }
134 }
135
136 enum {
137 SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
138 SAME_EXTENDED = 251,
139 FULL = 255
140 };
141
142 public:
143 // Constructor
144 StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,
145 int32_t code_len, TRAPSJavaThread* __the_thread__);
146
147 inline int32_t get_frame_count() const { return _frame_count; }
148 StackMapFrame* next(StackMapFrame* pre_frame, bool first,
149 u2 max_locals, u2 max_stack, TRAPSJavaThread* __the_thread__);
150
151 void check_end(TRAPSJavaThread* __the_thread__) {
152 if (!_stream->at_end()) {
153 StackMapStream::stackmap_format_error("wrong attribute size", CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
154 }
155 }
156};
157
158#endif // SHARE_CLASSFILE_STACKMAPTABLE_HPP

/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp

1/*
2 * Copyright (c) 1998, 2021, 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 */
24
25#ifndef SHARE_UTILITIES_EXCEPTIONS_HPP
26#define SHARE_UTILITIES_EXCEPTIONS_HPP
27
28#include "memory/allocation.hpp"
29#include "oops/oopsHierarchy.hpp"
30#include "utilities/ostream.hpp"
31#include "utilities/sizes.hpp"
32
33// This file provides the basic support for exception handling in the VM.
34// Note: We do not use C++ exceptions to avoid compiler dependencies and
35// unpredictable performance.
36//
37// Scheme: Exceptions are stored with the thread. There is never more
38// than one pending exception per thread. All functions that can throw
39// an exception carry a THREAD argument (usually the last argument and
40// declared with the TRAPS macro). Throwing an exception means setting
41// a pending exception in the thread. Upon return from a function that
42// can throw an exception, we must check if an exception is pending.
43// The CHECK macros do this in a convenient way. Carrying around the
44// thread provides also convenient access to it (e.g. for Handle
45// creation, w/o the need for recomputation).
46
47
48
49// Forward declarations to be independent of the include structure.
50
51class JavaThread;
52class Handle;
53class Symbol;
54class JavaCallArguments;
55class methodHandle;
56
57// The ThreadShadow class is a helper class to access the _pending_exception
58// field of the Thread class w/o having access to the Thread's interface (for
59// include hierachy reasons).
60
61class ThreadShadow: public CHeapObj<mtThread> {
62 friend class VMStructs;
63 friend class JVMCIVMStructs;
64
65 protected:
66 oop _pending_exception; // Thread has gc actions.
67 const char* _exception_file; // file information for exception (debugging only)
68 int _exception_line; // line information for exception (debugging only)
69 friend void check_ThreadShadow(); // checks _pending_exception offset
70
71 // The following virtual exists only to force creation of a vtable.
72 // We need ThreadShadow to have a vtable, even in product builds,
73 // so that its layout will start at an offset of zero relative to Thread.
74 // Some C++ compilers are so "clever" that they put the ThreadShadow
75 // base class at offset 4 in Thread (after Thread's vtable), if they
76 // notice that Thread has a vtable but ThreadShadow does not.
77 virtual void unused_initial_virtual() { }
78
79 public:
80 oop pending_exception() const { return _pending_exception; }
81 bool has_pending_exception() const { return _pending_exception != NULL__null; }
5
Calling 'oop::operator!='
8
Returning from 'oop::operator!='
9
Returning zero, which participates in a condition later
82 const char* exception_file() const { return _exception_file; }
83 int exception_line() const { return _exception_line; }
84
85 // Code generation support
86 static ByteSize pending_exception_offset() { return byte_offset_of(ThreadShadow, _pending_exception)in_ByteSize((int)(size_t)((intx)&(((ThreadShadow*)16)->
_pending_exception) - 16))
; }
87
88 // use THROW whenever possible!
89 void set_pending_exception(oop exception, const char* file, int line);
90
91 // use CLEAR_PENDING_EXCEPTION whenever possible!
92 void clear_pending_exception();
93
94 // use CLEAR_PENDING_NONASYNC_EXCEPTION to clear probable nonasync exception.
95 void clear_pending_nonasync_exception();
96
97 ThreadShadow() : _pending_exception(NULL__null),
98 _exception_file(NULL__null), _exception_line(0) {}
99};
100
101
102// Exceptions is a helper class that encapsulates all operations
103// that require access to the thread interface and which are
104// relatively rare. The Exceptions operations should only be
105// used directly if the macros below are insufficient.
106
107class Exceptions {
108 static bool special_exception(JavaThread* thread, const char* file, int line, Handle exception);
109 static bool special_exception(JavaThread* thread, const char* file, int line, Symbol* name, const char* message);
110
111 // Count out of memory errors that are interesting in error diagnosis
112 static volatile int _out_of_memory_error_java_heap_errors;
113 static volatile int _out_of_memory_error_metaspace_errors;
114 static volatile int _out_of_memory_error_class_metaspace_errors;
115
116 // Count linkage errors
117 static volatile int _linkage_errors;
118 public:
119 // this enum is defined to indicate whether it is safe to
120 // ignore the encoding scheme of the original message string.
121 typedef enum {
122 safe_to_utf8 = 0,
123 unsafe_to_utf8 = 1
124 } ExceptionMsgToUtf8Mode;
125 // Throw exceptions: w/o message, w/ message & with formatted message.
126 static void _throw_oop(JavaThread* thread, const char* file, int line, oop exception);
127 static void _throw(JavaThread* thread, const char* file, int line, Handle exception, const char* msg = NULL__null);
128
129 static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message);
130 static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message,
131 Handle loader, Handle protection_domain);
132
133 static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause);
134 static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
135 Handle h_loader, Handle h_protection_domain);
136
137 static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause);
138 static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause,
139 Handle h_loader, Handle h_protection_domain);
140
141 static void _throw_args(JavaThread* thread, const char* file, int line,
142 Symbol* name, Symbol* signature,
143 JavaCallArguments* args);
144
145 // There is no THROW... macro for this method. Caller should remember
146 // to do a return after calling it.
147 static void fthrow(JavaThread* thread, const char* file, int line, Symbol* name,
148 const char* format, ...) ATTRIBUTE_PRINTF(5, 6)__attribute__((format(printf, 5, 6)));
149
150 // Create and initialize a new exception
151 static Handle new_exception(JavaThread* thread, Symbol* name,
152 Symbol* signature, JavaCallArguments* args,
153 Handle loader, Handle protection_domain);
154
155 static Handle new_exception(JavaThread* thread, Symbol* name,
156 Symbol* signature, JavaCallArguments* args,
157 Handle cause,
158 Handle loader, Handle protection_domain);
159
160 static Handle new_exception(JavaThread* thread, Symbol* name,
161 Handle cause,
162 Handle loader, Handle protection_domain,
163 ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
164
165 static Handle new_exception(JavaThread* thread, Symbol* name,
166 const char* message, Handle cause,
167 Handle loader, Handle protection_domain,
168 ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
169
170 static Handle new_exception(JavaThread* thread, Symbol* name,
171 const char* message,
172 ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
173
174 static void throw_stack_overflow_exception(JavaThread* thread, const char* file, int line, const methodHandle& method);
175
176 static void throw_unsafe_access_internal_error(JavaThread* thread, const char* file, int line, const char* message);
177
178 static void wrap_dynamic_exception(bool is_indy, JavaThread* thread);
179
180 // Exception counting for error files of interesting exceptions that may have
181 // caused a problem for the jvm
182 static volatile int _stack_overflow_errors;
183
184 static bool has_exception_counts();
185 static void count_out_of_memory_exceptions(Handle exception);
186 static void print_exception_counts_on_error(outputStream* st);
187
188 // for AbortVMOnException flag
189 static void debug_check_abort(Handle exception, const char* message = NULL__null);
190 static void debug_check_abort_helper(Handle exception, const char* message = NULL__null);
191 static void debug_check_abort(const char *value_string, const char* message = NULL__null);
192
193 // for logging exceptions
194 static void log_exception(Handle exception, const char* message);
195};
196
197
198// The THREAD & TRAPS macros facilitate the declaration of functions that throw exceptions.
199// Convention: Use the TRAPS macro as the last argument of such a function; e.g.:
200//
201// int this_function_may_trap(int x, float y, TRAPS)
202
203#define THREAD__the_thread__ __the_thread__
204#define TRAPSJavaThread* __the_thread__ JavaThread* THREAD__the_thread__
205
206
207// The CHECK... macros should be used to pass along a THREAD reference and to check for pending
208// exceptions. In special situations it is necessary to handle pending exceptions explicitly,
209// in these cases the PENDING_EXCEPTION helper macros should be used.
210//
211// Macro naming conventions: Macros that end with _ require a result value to be returned. They
212// are for functions with non-void result type. The result value is usually ignored because of
213// the exception and is only needed for syntactic correctness. The _0 ending is a shortcut for
214// _(0) since this is a frequent case. Example:
215//
216// int result = this_function_may_trap(x_arg, y_arg, CHECK_0);
217//
218// CAUTION: make sure that the function call using a CHECK macro is not the only statement of a
219// conditional branch w/o enclosing {} braces, since the CHECK macros expand into several state-
220// ments! Also make sure it is not used on a function call that is part of a return statement!
221
222#define PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->pending_exception()) (((ThreadShadow*)THREAD__the_thread__)->pending_exception())
223#define HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception()) (((ThreadShadow*)THREAD__the_thread__)->has_pending_exception())
224#define CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception(
))
(((ThreadShadow*)THREAD__the_thread__)->clear_pending_exception())
225
226#define CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) return ; (void)(0
227#define CHECK_(result)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return result; (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) return result; (void)(0
228#define CHECK_0__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return 0; (void)(0
CHECK_(0)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return 0; (void)(0
229#define CHECK_NH__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return Handle(); (void)(0
CHECK_(Handle())__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return Handle(); (void)(0
230#define CHECK_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
CHECK_(NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
231#define CHECK_false__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return false; (void)(0
CHECK_(false)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return false; (void)(0
232#define CHECK_JNI_ERR__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return (-1); (void)(0
CHECK_(JNI_ERR)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return (-1); (void)(0
233
234// CAUTION: These macros clears all exceptions including async exceptions, use it with caution.
235#define CHECK_AND_CLEAR__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return; } (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception(
))
; return; } (void)(0
236#define CHECK_AND_CLEAR_(result)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return result; } (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception(
))
; return result; } (void)(0
237#define CHECK_AND_CLEAR_0__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return 0; } (void)(0
CHECK_AND_CLEAR_(0)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return 0; } (void)(0
238#define CHECK_AND_CLEAR_NH__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return Handle(); } (void)(0
CHECK_AND_CLEAR_(Handle())__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return Handle(); } (void)(0
239#define CHECK_AND_CLEAR_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return __null; } (void)(0
CHECK_AND_CLEAR_(NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return __null; } (void)(0
240#define CHECK_AND_CLEAR_false__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return false; } (void)(0
CHECK_AND_CLEAR_(false)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); return false; } (void)(0
241
242// CAUTION: These macros clears all exceptions except probable async exceptions j.l.InternalError and j.l.ThreadDeath.
243// So use it with caution.
244#define CLEAR_PENDING_NONASYNC_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
())
(((ThreadShadow*)THREAD__the_thread__)->clear_pending_nonasync_exception())
245#define CHECK_AND_CLEAR_NONASYNC__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return; } (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { CLEAR_PENDING_NONASYNC_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
())
; return; } (void)(0
246#define CHECK_AND_CLEAR_NONASYNC_(result)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return result; } (void)(0
THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { CLEAR_PENDING_NONASYNC_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
())
; return result; } (void)(0
247#define CHECK_AND_CLEAR_NONASYNC_0__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return 0; } (void)(0
CHECK_AND_CLEAR_NONASYNC_(0)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return 0; } (void)(0
248#define CHECK_AND_CLEAR_NONASYNC_NH__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return Handle(); } (void)(0
CHECK_AND_CLEAR_NONASYNC_(Handle())__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return Handle(); } (void)(0
249#define CHECK_AND_CLEAR_NONASYNC_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return __null; } (void)(0
CHECK_AND_CLEAR_NONASYNC_(NULL)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return __null; } (void)(0
250#define CHECK_AND_CLEAR_NONASYNC_false__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return false; } (void)(0
CHECK_AND_CLEAR_NONASYNC_(false)__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { (((ThreadShadow*)__the_thread__)->clear_pending_nonasync_exception
()); return false; } (void)(0
251
252// The THROW... macros should be used to throw an exception. They require a THREAD variable to be
253// visible within the scope containing the THROW. Usually this is achieved by declaring the function
254// with a TRAPS argument.
255
256#define THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 256
THREAD__the_thread__, __FILE__"/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp", __LINE__256
257
258#define THROW_OOP(e){ Exceptions::_throw_oop(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 258, e); return; }
\
259 { Exceptions::_throw_oop(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 259
, e); return; }
260
261#define THROW_HANDLE(e){ Exceptions::_throw(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 261, e); return; }
\
262 { Exceptions::_throw(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 262
, e); return; }
263
264#define THROW(name){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 264, name, __null); return; }
\
265 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 265
, name, NULL__null); return; }
266
267#define THROW_MSG(name, message){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 267, name, message); return; }
\
268 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 268
, name, message); return; }
269
270#define THROW_CAUSE(name, cause){ Exceptions::_throw_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 270, name, cause); return; }
\
271 { Exceptions::_throw_cause(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 271
, name, cause); return; }
272
273#define THROW_MSG_LOADER(name, message, loader, protection_domain){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 273, name, message, loader, protection_domain); return; }
\
274 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 274
, name, message, loader, protection_domain); return; }
275
276#define THROW_ARG(name, signature, args){ Exceptions::_throw_args(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 276, name, signature, args); return; }
\
277 { Exceptions::_throw_args(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 277
, name, signature, args); return; }
278
279#define THROW_OOP_(e, result){ Exceptions::_throw_oop(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 279, e); return result; }
\
280 { Exceptions::_throw_oop(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 280
, e); return result; }
281
282#define THROW_HANDLE_(e, result){ Exceptions::_throw(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 282, e); return result; }
\
283 { Exceptions::_throw(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 283
, e); return result; }
284
285#define THROW_(name, result){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 285, name, __null); return result; }
\
286 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 286
, name, NULL__null); return result; }
287
288#define THROW_MSG_(name, message, result){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 288, name, message); return result; }
\
289 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 289
, name, message); return result; }
290
291#define THROW_MSG_LOADER_(name, message, loader, protection_domain, result){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 291, name, message, loader, protection_domain); return result
; }
\
292 { Exceptions::_throw_msg(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 292
, name, message, loader, protection_domain); return result; }
293
294#define THROW_ARG_(name, signature, args, result){ Exceptions::_throw_args(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 294, name, signature, args); return result; }
\
295 { Exceptions::_throw_args(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 295
, name, signature, args); return result; }
296
297#define THROW_MSG_CAUSE(name, message, cause){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 297, name, message, cause); return; }
\
298 { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 298
, name, message, cause); return; }
299
300#define THROW_MSG_CAUSE_(name, message, cause, result){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 300, name, message, cause); return result; }
\
301 { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 301
, name, message, cause); return result; }
302
303
304#define THROW_OOP_0(e){ Exceptions::_throw_oop(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 304, e); return 0; }
THROW_OOP_(e, 0){ Exceptions::_throw_oop(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 304, e); return 0; }
305#define THROW_HANDLE_0(e){ Exceptions::_throw(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 305, e); return 0; }
THROW_HANDLE_(e, 0){ Exceptions::_throw(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 305, e); return 0; }
306#define THROW_0(name){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 306, name, __null); return 0; }
THROW_(name, 0){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 306, name, __null); return 0; }
307#define THROW_MSG_0(name, message){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 307, name, message); return 0; }
THROW_MSG_(name, message, 0){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 307, name, message); return 0; }
308#define THROW_WRAPPED_0(name, oop_to_wrap)THROW_WRAPPED_(name, oop_to_wrap, 0) THROW_WRAPPED_(name, oop_to_wrap, 0)
309#define THROW_ARG_0(name, signature, arg){ Exceptions::_throw_args(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 309, name, signature, arg); return 0; }
THROW_ARG_(name, signature, arg, 0){ Exceptions::_throw_args(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 309, name, signature, arg); return 0; }
310#define THROW_MSG_CAUSE_0(name, message, cause){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 310, name, message, cause); return 0; }
THROW_MSG_CAUSE_(name, message, cause, 0){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 310, name, message, cause); return 0; }
311#define THROW_MSG_CAUSE_NULL(name, message, cause){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 311, name, message, cause); return __null; }
THROW_MSG_CAUSE_(name, message, cause, NULL){ Exceptions::_throw_msg_cause(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 311, name, message, cause); return __null; }
312
313#define THROW_NULL(name){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 313, name, __null); return __null; }
THROW_(name, NULL){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 313, name, __null); return __null; }
314#define THROW_MSG_NULL(name, message){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 314, name, message); return __null; }
THROW_MSG_(name, message, NULL){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 314, name, message); return __null; }
315
316// The CATCH macro checks that no exception has been thrown by a function; it is used at
317// call sites about which is statically known that the callee cannot throw an exception
318// even though it is declared with TRAPS.
319
320#define CATCH__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) { oop ex = (((ThreadShadow*)__the_thread__)->pending_exception
()); (((ThreadShadow*)__the_thread__)->clear_pending_exception
()); ex->print(); do { if (!(false)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 320, "assert(" "false" ") failed", "CATCH"); ::breakpoint()
; } } while (0); } (void)(0
\
321 THREAD__the_thread__); if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { \
322 oop ex = PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->pending_exception()); \
323 CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception(
))
; \
324 DEBUG_ONLY(ex->print();)ex->print(); \
325 assert(false, "CATCH")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/exceptions.hpp"
, 325, "assert(" "false" ") failed", "CATCH"); ::breakpoint()
; } } while (0)
; \
326 } (void)(0
327
328// ExceptionMark is a stack-allocated helper class for local exception handling.
329// It is used with the EXCEPTION_MARK macro.
330
331class ExceptionMark {
332 private:
333 JavaThread* _thread;
334 inline void check_no_pending_exception();
335
336 public:
337 ExceptionMark();
338 ExceptionMark(JavaThread* thread);
339 ~ExceptionMark();
340
341 JavaThread* thread() {
342 return _thread;
343 }
344};
345
346// Use an EXCEPTION_MARK for 'local' exceptions. EXCEPTION_MARK makes sure that no
347// pending exception exists upon entering its scope and tests that no pending exception
348// exists when leaving the scope.
349
350// See also preserveException.hpp for PreserveExceptionMark
351// which preserves pre-existing exceptions and does not allow new
352// exceptions.
353
354#define EXCEPTION_MARKExceptionMark __em; JavaThread* __the_thread__ = __em.thread(
);
ExceptionMark __em; JavaThread* THREAD__the_thread__ = __em.thread();
355
356#endif // SHARE_UTILITIES_EXCEPTIONS_HPP

/home/daniel/Projects/java/jdk/src/hotspot/share/oops/oopsHierarchy.hpp

1/*
2 * Copyright (c) 1997, 2020, 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 */
24
25#ifndef SHARE_OOPS_OOPSHIERARCHY_HPP
26#define SHARE_OOPS_OOPSHIERARCHY_HPP
27
28#include "metaprogramming/integralConstant.hpp"
29#include "metaprogramming/primitiveConversions.hpp"
30#include "utilities/globalDefinitions.hpp"
31
32// OBJECT hierarchy
33// This hierarchy is a representation hierarchy, i.e. if A is a superclass
34// of B, A's representation is a prefix of B's representation.
35
36// Global offset instead of address for an oop within a java object.
37enum class narrowOop : uint32_t { null = 0 };
38
39// If compressed klass pointers then use narrowKlass.
40typedef juint narrowKlass;
41
42typedef void* OopOrNarrowOopStar;
43
44#ifndef CHECK_UNHANDLED_OOPS1
45
46typedef class oopDesc* oop;
47typedef class instanceOopDesc* instanceOop;
48typedef class arrayOopDesc* arrayOop;
49typedef class objArrayOopDesc* objArrayOop;
50typedef class typeArrayOopDesc* typeArrayOop;
51
52#else
53
54// When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a
55// carefully chosen set of constructors and conversion operators to go
56// to and from the underlying oopDesc pointer type.
57//
58// Because oop and its subclasses <type>Oop are class types, arbitrary
59// conversions are not accepted by the compiler. Applying a cast to
60// an oop will cause the best matched conversion operator to be
61// invoked returning the underlying oopDesc* type if appropriate.
62// No copy constructors, explicit user conversions or operators of
63// numerical type should be defined within the oop class. Most C++
64// compilers will issue a compile time error concerning the overloading
65// ambiguity between operators of numerical and pointer types. If
66// a conversion to or from an oop to a numerical type is needed,
67// use the inline template methods, cast_*_oop, defined below.
68//
69// Converting NULL to oop to Handle implicit is no longer accepted by the
70// compiler because there are too many steps in the conversion. Use Handle()
71// instead, which generates less code anyway.
72
73class Thread;
74class oopDesc;
75
76extern "C" bool CheckUnhandledOops;
77
78class oop {
79 oopDesc* _o;
80
81 void register_oop();
82 void unregister_oop();
83
84 void register_if_checking() {
85 if (CheckUnhandledOops) register_oop();
86 }
87
88public:
89 oop() : _o(nullptr) { register_if_checking(); }
90 oop(const oop& o) : _o(o._o) { register_if_checking(); }
91 oop(oopDesc* o) : _o(o) { register_if_checking(); }
92 ~oop() {
93 if (CheckUnhandledOops) unregister_oop();
94 }
95
96 oopDesc* obj() const { return _o; }
97 oopDesc* operator->() const { return _o; }
98 operator oopDesc* () const { return _o; }
99
100 bool operator==(const oop& o) const { return _o == o._o; }
101 bool operator!=(const oop& o) const { return _o != o._o; }
102
103 bool operator==(std::nullptr_t) const { return _o == nullptr; }
104 bool operator!=(std::nullptr_t) const { return _o != nullptr; }
6
Assuming the condition is false
7
Returning zero, which participates in a condition later
105
106 oop& operator=(const oop& o) { _o = o._o; return *this; }
107};
108
109template<>
110struct PrimitiveConversions::Translate<oop> : public TrueType {
111 typedef oop Value;
112 typedef oopDesc* Decayed;
113
114 static Decayed decay(Value x) { return x.obj(); }
115 static Value recover(Decayed x) { return oop(x); }
116};
117
118#define DEF_OOP(type)class typeOopDesc; class typeOop : public oop { public: typeOop
() : oop() {} typeOop(const typeOop& o) : oop(o) {} typeOop
(const oop& o) : oop(o) {} typeOop(typeOopDesc* o) : oop(
(oopDesc*)o) {} operator typeOopDesc* () const { return (typeOopDesc
*)obj(); } typeOopDesc* operator->() const { return (typeOopDesc
*)obj(); } typeOop& operator=(const typeOop& o) { oop
::operator=(o); return *this; } }; template<> struct PrimitiveConversions
::Translate<typeOop> : public TrueType { typedef typeOop
Value; typedef typeOopDesc* Decayed; static Decayed decay(Value
x) { return (typeOopDesc*)x.obj(); } static Value recover(Decayed
x) { return typeOop(x); } };
\
119 class type##OopDesc; \
120 class type##Oop : public oop { \
121 public: \
122 type##Oop() : oop() {} \
123 type##Oop(const type##Oop& o) : oop(o) {} \
124 type##Oop(const oop& o) : oop(o) {} \
125 type##Oop(type##OopDesc* o) : oop((oopDesc*)o) {} \
126 operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
127 type##OopDesc* operator->() const { \
128 return (type##OopDesc*)obj(); \
129 } \
130 type##Oop& operator=(const type##Oop& o) { \
131 oop::operator=(o); \
132 return *this; \
133 } \
134 }; \
135 \
136 template<> \
137 struct PrimitiveConversions::Translate<type##Oop> : public TrueType { \
138 typedef type##Oop Value; \
139 typedef type##OopDesc* Decayed; \
140 \
141 static Decayed decay(Value x) { return (type##OopDesc*)x.obj(); } \
142 static Value recover(Decayed x) { return type##Oop(x); } \
143 };
144
145DEF_OOP(instance)class instanceOopDesc; class instanceOop : public oop { public
: instanceOop() : oop() {} instanceOop(const instanceOop&
o) : oop(o) {} instanceOop(const oop& o) : oop(o) {} instanceOop
(instanceOopDesc* o) : oop((oopDesc*)o) {} operator instanceOopDesc
* () const { return (instanceOopDesc*)obj(); } instanceOopDesc
* operator->() const { return (instanceOopDesc*)obj(); } instanceOop
& operator=(const instanceOop& o) { oop::operator=(o)
; return *this; } }; template<> struct PrimitiveConversions
::Translate<instanceOop> : public TrueType { typedef instanceOop
Value; typedef instanceOopDesc* Decayed; static Decayed decay
(Value x) { return (instanceOopDesc*)x.obj(); } static Value recover
(Decayed x) { return instanceOop(x); } };
;
146DEF_OOP(array)class arrayOopDesc; class arrayOop : public oop { public: arrayOop
() : oop() {} arrayOop(const arrayOop& o) : oop(o) {} arrayOop
(const oop& o) : oop(o) {} arrayOop(arrayOopDesc* o) : oop
((oopDesc*)o) {} operator arrayOopDesc* () const { return (arrayOopDesc
*)obj(); } arrayOopDesc* operator->() const { return (arrayOopDesc
*)obj(); } arrayOop& operator=(const arrayOop& o) { oop
::operator=(o); return *this; } }; template<> struct PrimitiveConversions
::Translate<arrayOop> : public TrueType { typedef arrayOop
Value; typedef arrayOopDesc* Decayed; static Decayed decay(Value
x) { return (arrayOopDesc*)x.obj(); } static Value recover(Decayed
x) { return arrayOop(x); } };
;
147DEF_OOP(objArray)class objArrayOopDesc; class objArrayOop : public oop { public
: objArrayOop() : oop() {} objArrayOop(const objArrayOop&
o) : oop(o) {} objArrayOop(const oop& o) : oop(o) {} objArrayOop
(objArrayOopDesc* o) : oop((oopDesc*)o) {} operator objArrayOopDesc
* () const { return (objArrayOopDesc*)obj(); } objArrayOopDesc
* operator->() const { return (objArrayOopDesc*)obj(); } objArrayOop
& operator=(const objArrayOop& o) { oop::operator=(o)
; return *this; } }; template<> struct PrimitiveConversions
::Translate<objArrayOop> : public TrueType { typedef objArrayOop
Value; typedef objArrayOopDesc* Decayed; static Decayed decay
(Value x) { return (objArrayOopDesc*)x.obj(); } static Value recover
(Decayed x) { return objArrayOop(x); } };
;
148DEF_OOP(typeArray)class typeArrayOopDesc; class typeArrayOop : public oop { public
: typeArrayOop() : oop() {} typeArrayOop(const typeArrayOop&
o) : oop(o) {} typeArrayOop(const oop& o) : oop(o) {} typeArrayOop
(typeArrayOopDesc* o) : oop((oopDesc*)o) {} operator typeArrayOopDesc
* () const { return (typeArrayOopDesc*)obj(); } typeArrayOopDesc
* operator->() const { return (typeArrayOopDesc*)obj(); } typeArrayOop
& operator=(const typeArrayOop& o) { oop::operator=(o
); return *this; } }; template<> struct PrimitiveConversions
::Translate<typeArrayOop> : public TrueType { typedef typeArrayOop
Value; typedef typeArrayOopDesc* Decayed; static Decayed decay
(Value x) { return (typeArrayOopDesc*)x.obj(); } static Value
recover(Decayed x) { return typeArrayOop(x); } };
;
149
150#endif // CHECK_UNHANDLED_OOPS
151
152// Cast functions to convert to and from oops.
153template <typename T> inline oop cast_to_oop(T value) {
154 return (oopDesc*)value;
155}
156template <typename T> inline T cast_from_oop(oop o) {
157 return (T)(CHECK_UNHANDLED_OOPS_ONLY((oopDesc*))(oopDesc*)o);
158}
159
160// The metadata hierarchy is separate from the oop hierarchy
161
162// class MetaspaceObj
163class ConstMethod;
164class ConstantPoolCache;
165class MethodData;
166// class Metadata
167class Method;
168class ConstantPool;
169// class CHeapObj
170class CompiledICHolder;
171
172
173// The klass hierarchy is separate from the oop hierarchy.
174
175class Klass;
176class InstanceKlass;
177class InstanceMirrorKlass;
178class InstanceClassLoaderKlass;
179class InstanceRefKlass;
180class ArrayKlass;
181class ObjArrayKlass;
182class TypeArrayKlass;
183
184#endif // SHARE_OOPS_OOPSHIERARCHY_HPP