Bug Summary

File:jdk/src/hotspot/share/oops/constMethod.hpp
Warning:line 449, column 7
Null pointer passed to 2nd parameter expecting 'nonnull'

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 defaultMethods.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/defaultMethods.cpp

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

1/*
2 * Copyright (c) 2012, 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#include "precompiled.hpp"
26#include "classfile/bytecodeAssembler.hpp"
27#include "classfile/defaultMethods.hpp"
28#include "classfile/symbolTable.hpp"
29#include "classfile/systemDictionary.hpp"
30#include "classfile/vmClasses.hpp"
31#include "classfile/vmSymbols.hpp"
32#include "logging/log.hpp"
33#include "logging/logStream.hpp"
34#include "memory/allocation.hpp"
35#include "memory/metadataFactory.hpp"
36#include "memory/resourceArea.hpp"
37#include "memory/universe.hpp"
38#include "prims/jvmtiExport.hpp"
39#include "runtime/arguments.hpp"
40#include "runtime/handles.inline.hpp"
41#include "runtime/signature.hpp"
42#include "runtime/thread.hpp"
43#include "oops/instanceKlass.hpp"
44#include "oops/klass.hpp"
45#include "oops/method.hpp"
46#include "utilities/accessFlags.hpp"
47#include "utilities/exceptions.hpp"
48#include "utilities/ostream.hpp"
49#include "utilities/pair.hpp"
50#include "utilities/resourceHash.hpp"
51
52typedef enum { QUALIFIED, DISQUALIFIED } QualifiedState;
53
54static void print_slot(outputStream* str, Symbol* name, Symbol* signature) {
55 str->print("%s%s", name->as_C_string(), signature->as_C_string());
56}
57
58static void print_method(outputStream* str, Method* mo, bool with_class=true) {
59 if (with_class) {
60 str->print("%s.", mo->klass_name()->as_C_string());
61 }
62 print_slot(str, mo->name(), mo->signature());
63}
64
65/**
66 * Perform a depth-first iteration over the class hierarchy, applying
67 * algorithmic logic as it goes.
68 *
69 * This class is one half of the inheritance hierarchy analysis mechanism.
70 * It is meant to be used in conjunction with another class, the algorithm,
71 * which is indicated by the ALGO template parameter. This class can be
72 * paired with any algorithm class that provides the required methods.
73 *
74 * This class contains all the mechanics for iterating over the class hierarchy
75 * starting at a particular root, without recursing (thus limiting stack growth
76 * from this point). It visits each superclass (if present) and superinterface
77 * in a depth-first manner, with callbacks to the ALGO class as each class is
78 * encountered (visit()), The algorithm can cut-off further exploration of a
79 * particular branch by returning 'false' from a visit() call.
80 *
81 * The ALGO class, must provide a visit() method, which each of which will be
82 * called once for each node in the inheritance tree during the iteration. In
83 * addition, it can provide a memory block via new_node_data(), which it can
84 * use for node-specific storage (and access via the current_data() and
85 * data_at_depth(int) methods).
86 *
87 * Bare minimum needed to be an ALGO class:
88 * class Algo : public HierarchyVisitor<Algo> {
89 * void* new_node_data() { return NULL; }
90 * void free_node_data(void* data) { return; }
91 * bool visit() { return true; }
92 * };
93 */
94template <class ALGO>
95class HierarchyVisitor : StackObj {
96 private:
97
98 class Node : public ResourceObj {
99 public:
100 InstanceKlass* _class;
101 bool _super_was_visited;
102 int _interface_index;
103 void* _algorithm_data;
104
105 Node(InstanceKlass* cls, void* data, bool visit_super)
106 : _class(cls), _super_was_visited(!visit_super),
107 _interface_index(0), _algorithm_data(data) {}
108
109 void update(InstanceKlass* cls, void* data, bool visit_super) {
110 _class = cls;
111 _super_was_visited = !visit_super;
112 _interface_index = 0;
113 _algorithm_data = data;
114 }
115 int number_of_interfaces() { return _class->local_interfaces()->length(); }
116 int interface_index() { return _interface_index; }
117 void set_super_visited() { _super_was_visited = true; }
118 void increment_visited_interface() { ++_interface_index; }
119 void set_all_interfaces_visited() {
120 _interface_index = number_of_interfaces();
121 }
122 bool has_visited_super() { return _super_was_visited; }
123 bool has_visited_all_interfaces() {
124 return interface_index() >= number_of_interfaces();
125 }
126 InstanceKlass* interface_at(int index) {
127 return _class->local_interfaces()->at(index);
128 }
129 InstanceKlass* next_super() { return _class->java_super(); }
130 InstanceKlass* next_interface() {
131 return interface_at(interface_index());
132 }
133 };
134
135 bool _visited_Object;
136
137 GrowableArray<Node*> _path;
138 GrowableArray<Node*> _free_nodes;
139
140 Node* current_top() const { return _path.top(); }
141 bool has_more_nodes() const { return _path.length() > 0; }
142 void push(InstanceKlass* cls, ALGO* algo) {
143 assert(cls != NULL, "Requires a valid instance class")do { if (!(cls != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 143, "assert(" "cls != __null" ") failed", "Requires a valid instance class"
); ::breakpoint(); } } while (0)
;
144 if (cls == vmClasses::Object_klass()) {
145 _visited_Object = true;
146 }
147 void* data = algo->new_node_data();
148 Node* node;
149 if (_free_nodes.is_empty()) { // Add a new node
150 node = new Node(cls, data, has_super(cls));
151 } else { // Reuse existing node and data
152 node = _free_nodes.pop();
153 node->update(cls, data, has_super(cls));
154 }
155 _path.push(node);
156 }
157 void pop() {
158 Node* node = _path.pop();
159 // Make the node available for reuse
160 _free_nodes.push(node);
161 }
162
163 // Since the starting point can be an interface, we must ensure we catch
164 // j.l.Object as the super once in those cases. The _visited_Object flag
165 // only ensures we don't then repeatedly enqueue Object for each interface
166 // in the class hierarchy.
167 bool has_super(InstanceKlass* cls) {
168 return cls->super() != NULL__null && (!_visited_Object || !cls->is_interface());
169 }
170
171 Node* node_at_depth(int i) const {
172 return (i >= _path.length()) ? NULL__null : _path.at(_path.length() - i - 1);
173 }
174
175 protected:
176
177 // Resets the visitor
178 void reset() {
179 _visited_Object = false;
180 }
181
182 // Accessors available to the algorithm
183 int current_depth() const { return _path.length() - 1; }
184
185 InstanceKlass* class_at_depth(int i) {
186 Node* n = node_at_depth(i);
187 return n == NULL__null ? NULL__null : n->_class;
188 }
189 InstanceKlass* current_class() { return class_at_depth(0); }
190
191 void* data_at_depth(int i) {
192 Node* n = node_at_depth(i);
193 return n == NULL__null ? NULL__null : n->_algorithm_data;
194 }
195 void* current_data() { return data_at_depth(0); }
196
197 public:
198 HierarchyVisitor() : _visited_Object(false), _path() {}
199
200 void run(InstanceKlass* root) {
201 ALGO* algo = static_cast<ALGO*>(this);
202
203 push(root, algo);
204 bool top_needs_visit = true;
205 do {
206 Node* top = current_top();
207 if (top_needs_visit) {
208 if (algo->visit() == false) {
209 // algorithm does not want to continue along this path. Arrange
210 // it so that this state is immediately popped off the stack
211 top->set_super_visited();
212 top->set_all_interfaces_visited();
213 }
214 top_needs_visit = false;
215 }
216
217 if (top->has_visited_super() && top->has_visited_all_interfaces()) {
218 algo->free_node_data(top->_algorithm_data);
219 pop();
220 } else {
221 InstanceKlass* next = NULL__null;
222 if (top->has_visited_super() == false) {
223 next = top->next_super();
224 top->set_super_visited();
225 } else {
226 next = top->next_interface();
227 top->increment_visited_interface();
228 }
229 assert(next != NULL, "Otherwise we shouldn't be here")do { if (!(next != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 229, "assert(" "next != __null" ") failed", "Otherwise we shouldn't be here"
); ::breakpoint(); } } while (0)
;
230 push(next, algo);
231 top_needs_visit = true;
232 }
233 } while (has_more_nodes());
234 }
235};
236
237class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
238 private:
239 outputStream* _st;
240 public:
241 bool visit() {
242 InstanceKlass* cls = current_class();
243 streamIndentor si(_st, current_depth() * 2);
244 _st->indent().print_cr("%s", cls->name()->as_C_string());
245 return true;
246 }
247
248 void* new_node_data() { return NULL__null; }
249 void free_node_data(void* data) { return; }
250
251 PrintHierarchy(outputStream* st = tty) : _st(st) {}
252};
253
254// Used to register InstanceKlass objects and all related metadata structures
255// (Methods, ConstantPools) as "in-use" by the current thread so that they can't
256// be deallocated by class redefinition while we're using them. The classes are
257// de-registered when this goes out of scope.
258//
259// Once a class is registered, we need not bother with methodHandles or
260// constantPoolHandles for it's associated metadata.
261class KeepAliveRegistrar : public StackObj {
262 private:
263 Thread* _thread;
264 GrowableArray<ConstantPool*> _keep_alive;
265
266 public:
267 KeepAliveRegistrar(Thread* thread) : _thread(thread), _keep_alive(6) {
268 assert(thread == Thread::current(), "Must be current thread")do { if (!(thread == Thread::current())) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 268, "assert(" "thread == Thread::current()" ") failed", "Must be current thread"
); ::breakpoint(); } } while (0)
;
269 }
270
271 ~KeepAliveRegistrar() {
272 for (int i = _keep_alive.length() - 1; i >= 0; --i) {
273 ConstantPool* cp = _keep_alive.at(i);
274 int idx = _thread->metadata_handles()->find_from_end(cp);
275 assert(idx > 0, "Must be in the list")do { if (!(idx > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 275, "assert(" "idx > 0" ") failed", "Must be in the list"
); ::breakpoint(); } } while (0)
;
276 _thread->metadata_handles()->remove_at(idx);
277 }
278 }
279
280 // Register a class as 'in-use' by the thread. It's fine to register a class
281 // multiple times (though perhaps inefficient)
282 void register_class(InstanceKlass* ik) {
283 ConstantPool* cp = ik->constants();
284 _keep_alive.push(cp);
285 _thread->metadata_handles()->push(cp);
286 }
287};
288
289class KeepAliveVisitor : public HierarchyVisitor<KeepAliveVisitor> {
290 private:
291 KeepAliveRegistrar* _registrar;
292
293 public:
294 KeepAliveVisitor(KeepAliveRegistrar* registrar) : _registrar(registrar) {}
295
296 void* new_node_data() { return NULL__null; }
297 void free_node_data(void* data) { return; }
298
299 bool visit() {
300 _registrar->register_class(current_class());
301 return true;
302 }
303};
304
305
306// A method family contains a set of all methods that implement a single
307// erased method. As members of the set are collected while walking over the
308// hierarchy, they are tagged with a qualification state. The qualification
309// state for an erased method is set to disqualified if there exists a path
310// from the root of hierarchy to the method that contains an interleaving
311// erased method defined in an interface.
312
313class MethodState {
314 public:
315 Method* _method;
316 QualifiedState _state;
317
318 MethodState() : _method(NULL__null), _state(DISQUALIFIED) {}
319 MethodState(Method* method, QualifiedState state) : _method(method), _state(state) {}
320};
321
322class MethodFamily : public ResourceObj {
323 private:
324
325 GrowableArray<MethodState> _members;
326
327 Method* _selected_target; // Filled in later, if a unique target exists
328 Symbol* _exception_message; // If no unique target is found
329 Symbol* _exception_name; // If no unique target is found
330
331 MethodState* find_method(Method* method) {
332 for (int i = 0; i < _members.length(); i++) {
333 if (_members.at(i)._method == method) {
334 return &_members.at(i);
335 }
336 }
337 return NULL__null;
338 }
339
340 void add_method(Method* method, QualifiedState state) {
341 MethodState method_state(method, state);
342 _members.append(method_state);
343 }
344
345 Symbol* generate_no_defaults_message() const;
346 Symbol* generate_method_message(Symbol *klass_name, Method* method) const;
347 Symbol* generate_conflicts_message(GrowableArray<MethodState>* methods) const;
348
349 public:
350
351 MethodFamily()
352 : _selected_target(NULL__null), _exception_message(NULL__null), _exception_name(NULL__null) {}
353
354 void set_target_if_empty(Method* m) {
355 if (_selected_target == NULL__null && !m->is_overpass()) {
356 _selected_target = m;
357 }
358 }
359
360 void record_method(Method* m, QualifiedState state) {
361 // If not in the set, add it. If it's already in the set, then leave it
362 // as is if state is qualified, or set it to disqualified if state is
363 // disqualified.
364 MethodState* method_state = find_method(m);
365 if (method_state == NULL__null) {
366 add_method(m, state);
367 } else if (state == DISQUALIFIED) {
368 method_state->_state = DISQUALIFIED;
369 }
370 }
371
372 bool has_target() const { return _selected_target != NULL__null; }
373 bool throws_exception() { return _exception_message != NULL__null; }
374
375 Method* get_selected_target() { return _selected_target; }
376 Symbol* get_exception_message() { return _exception_message; }
377 Symbol* get_exception_name() { return _exception_name; }
378
379 // Either sets the target or the exception error message
380 void determine_target_or_set_exception_message(InstanceKlass* root) {
381 if (has_target() || throws_exception()) {
382 return;
383 }
384
385 // Qualified methods are maximally-specific methods
386 // These include public, instance concrete (=default) and abstract methods
387 int num_defaults = 0;
388 int default_index = -1;
389 for (int i = 0; i < _members.length(); i++) {
390 MethodState &member = _members.at(i);
391 if (member._state == QUALIFIED) {
392 if (member._method->is_default_method()) {
393 num_defaults++;
394 default_index = i;
395 }
396 }
397 }
398
399 if (num_defaults == 1) {
400 assert(_members.at(default_index)._state == QUALIFIED, "")do { if (!(_members.at(default_index)._state == QUALIFIED)) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 400, "assert(" "_members.at(default_index)._state == QUALIFIED"
") failed", ""); ::breakpoint(); } } while (0)
;
401 _selected_target = _members.at(default_index)._method;
402 } else {
403 generate_and_set_exception_message(root, num_defaults, default_index);
404 }
405 }
406
407 void generate_and_set_exception_message(InstanceKlass* root, int num_defaults, int default_index) {
408 assert(num_defaults != 1, "invariant - should've been handled calling method")do { if (!(num_defaults != 1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 408, "assert(" "num_defaults != 1" ") failed", "invariant - should've been handled calling method"
); ::breakpoint(); } } while (0)
;
409
410 GrowableArray<Method*> qualified_methods;
411 for (int i = 0; i < _members.length(); i++) {
412 MethodState& member = _members.at(i);
413 if (member._state == QUALIFIED) {
414 qualified_methods.push(member._method);
415 }
416 }
417 if (num_defaults == 0) {
418 // If the root klass has a static method with matching name and signature
419 // then do not generate an overpass method because it will hide the
420 // static method during resolution.
421 if (qualified_methods.length() == 0) {
422 _exception_message = generate_no_defaults_message();
423 } else {
424 assert(root != NULL, "Null root class")do { if (!(root != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 424, "assert(" "root != __null" ") failed", "Null root class"
); ::breakpoint(); } } while (0)
;
425 _exception_message = generate_method_message(root->name(), qualified_methods.at(0));
426 }
427 _exception_name = vmSymbols::java_lang_AbstractMethodError();
428 } else {
429 _exception_message = generate_conflicts_message(&_members);
430 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
431 LogTarget(Debug, defaultmethods)LogTargetImpl<LogLevel::Debug, (LogTag::_defaultmethods), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG)>
lt;
432 if (lt.is_enabled()) {
433 LogStream ls(lt);
434 _exception_message->print_value_on(&ls);
435 ls.cr();
436 }
437 }
438 }
439
440 void print_selected(outputStream* str, int indent) const {
441 assert(has_target(), "Should be called otherwise")do { if (!(has_target())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 441, "assert(" "has_target()" ") failed", "Should be called otherwise"
); ::breakpoint(); } } while (0)
;
442 streamIndentor si(str, indent * 2);
443 str->indent().print("Selected method: ");
444 print_method(str, _selected_target);
445 Klass* method_holder = _selected_target->method_holder();
446 if (!method_holder->is_interface()) {
447 str->print(" : in superclass");
448 }
449 str->cr();
450 }
451
452 void print_exception(outputStream* str, int indent) {
453 assert(throws_exception(), "Should be called otherwise")do { if (!(throws_exception())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 453, "assert(" "throws_exception()" ") failed", "Should be called otherwise"
); ::breakpoint(); } } while (0)
;
454 assert(_exception_name != NULL, "exception_name should be set")do { if (!(_exception_name != __null)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 454, "assert(" "_exception_name != __null" ") failed", "exception_name should be set"
); ::breakpoint(); } } while (0)
;
455 streamIndentor si(str, indent * 2);
456 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
457 }
458};
459
460Symbol* MethodFamily::generate_no_defaults_message() const {
461 return SymbolTable::new_symbol("No qualifying defaults found");
462}
463
464Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method) const {
465 stringStream ss;
466 ss.print("Method ");
467 Symbol* name = method->name();
468 Symbol* signature = method->signature();
469 ss.write((const char*)klass_name->bytes(), klass_name->utf8_length());
470 ss.print(".");
471 ss.write((const char*)name->bytes(), name->utf8_length());
472 ss.write((const char*)signature->bytes(), signature->utf8_length());
473 ss.print(" is abstract");
474 return SymbolTable::new_symbol(ss.base(), (int)ss.size());
475}
476
477Symbol* MethodFamily::generate_conflicts_message(GrowableArray<MethodState>* methods) const {
478 stringStream ss;
479 ss.print("Conflicting default methods:");
480 for (int i = 0; i < methods->length(); ++i) {
481 Method *method = methods->at(i)._method;
482 Symbol *klass = method->klass_name();
483 Symbol *name = method->name();
484 ss.print(" ");
485 ss.write((const char*) klass->bytes(), klass->utf8_length());
486 ss.print(".");
487 ss.write((const char*) name->bytes(), name->utf8_length());
488 }
489 return SymbolTable::new_symbol(ss.base(), (int)ss.size());
490}
491
492
493class StateRestorerScope;
494
495// StatefulMethodFamily is a wrapper around a MethodFamily that maintains the
496// qualification state during hierarchy visitation, and applies that state
497// when adding members to the MethodFamily
498class StatefulMethodFamily : public ResourceObj {
499 friend class StateRestorer;
500 private:
501 QualifiedState _qualification_state;
502
503 void set_qualification_state(QualifiedState state) {
504 _qualification_state = state;
505 }
506
507 protected:
508 MethodFamily _method_family;
509
510 public:
511 StatefulMethodFamily() {
512 _qualification_state = QUALIFIED;
513 }
514
515 void set_target_if_empty(Method* m) { _method_family.set_target_if_empty(m); }
516
517 MethodFamily* get_method_family() { return &_method_family; }
518
519 void record_method_and_dq_further(StateRestorerScope* scope, Method* mo);
520};
521
522// Because we use an iterative algorithm when iterating over the type
523// hierarchy, we can't use traditional scoped objects which automatically do
524// cleanup in the destructor when the scope is exited. StateRestorerScope (and
525// StateRestorer) provides a similar functionality, but for when you want a
526// scoped object in non-stack memory (such as in resource memory, as we do
527// here). You've just got to remember to call 'restore_state()' on the scope when
528// leaving it (and marks have to be explicitly added). The scope is reusable after
529// 'restore_state()' has been called.
530class StateRestorer : public ResourceObj {
531 public:
532 StatefulMethodFamily* _method;
533 QualifiedState _state_to_restore;
534
535 StateRestorer() : _method(NULL__null), _state_to_restore(DISQUALIFIED) {}
536
537 void restore_state() { _method->set_qualification_state(_state_to_restore); }
538};
539
540class StateRestorerScope : public ResourceObj {
541 private:
542 GrowableArray<StateRestorer*> _marks;
543 GrowableArray<StateRestorer*>* _free_list; // Shared between scopes
544 public:
545 StateRestorerScope(GrowableArray<StateRestorer*>* free_list) : _marks(), _free_list(free_list) {}
546
547 static StateRestorerScope* cast(void* data) {
548 return static_cast<StateRestorerScope*>(data);
549 }
550
551 void mark(StatefulMethodFamily* family, QualifiedState qualification_state) {
552 StateRestorer* restorer;
553 if (!_free_list->is_empty()) {
554 restorer = _free_list->pop();
555 } else {
556 restorer = new StateRestorer();
557 }
558 restorer->_method = family;
559 restorer->_state_to_restore = qualification_state;
560 _marks.append(restorer);
561 }
562
563#ifdef ASSERT1
564 bool is_empty() {
565 return _marks.is_empty();
566 }
567#endif
568
569 void restore_state() {
570 while(!_marks.is_empty()) {
571 StateRestorer* restorer = _marks.pop();
572 restorer->restore_state();
573 _free_list->push(restorer);
574 }
575 }
576};
577
578void StatefulMethodFamily::record_method_and_dq_further(StateRestorerScope* scope, Method* mo) {
579 scope->mark(this, _qualification_state);
580 _method_family.record_method(mo, _qualification_state);
581
582 // Everything found "above"??? this method in the hierarchy walk is set to
583 // disqualified
584 set_qualification_state(DISQUALIFIED);
585}
586
587// Represents a location corresponding to a vtable slot for methods that
588// neither the class nor any of it's ancestors provide an implementaion.
589// Default methods may be present to fill this slot.
590class EmptyVtableSlot : public ResourceObj {
591 private:
592 Symbol* _name;
593 Symbol* _signature;
594 int _size_of_parameters;
595 MethodFamily* _binding;
596
597 public:
598 EmptyVtableSlot(Method* method)
599 : _name(method->name()), _signature(method->signature()),
600 _size_of_parameters(method->size_of_parameters()), _binding(NULL__null) {}
601
602 Symbol* name() const { return _name; }
603 Symbol* signature() const { return _signature; }
604 int size_of_parameters() const { return _size_of_parameters; }
605
606 void bind_family(MethodFamily* lm) { _binding = lm; }
607 bool is_bound() { return _binding != NULL__null; }
608 MethodFamily* get_binding() { return _binding; }
609
610 void print_on(outputStream* str) const {
611 print_slot(str, name(), signature());
612 }
613};
614
615static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) {
616 bool found = false;
617 for (int j = 0; j < slots->length(); ++j) {
618 if (slots->at(j)->name() == m->name() &&
619 slots->at(j)->signature() == m->signature() ) {
620 found = true;
621 break;
622 }
623 }
624 return found;
625}
626
627static void find_empty_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots,
628 InstanceKlass* klass, const GrowableArray<Method*>* mirandas) {
629
630 assert(klass != NULL, "Must be valid class")do { if (!(klass != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 630, "assert(" "klass != __null" ") failed", "Must be valid class"
); ::breakpoint(); } } while (0)
;
631
632 // All miranda methods are obvious candidates
633 for (int i = 0; i < mirandas->length(); ++i) {
634 Method* m = mirandas->at(i);
635 if (!already_in_vtable_slots(slots, m)) {
636 slots->append(new EmptyVtableSlot(m));
637 }
638 }
639
640 // Also any overpasses in our superclasses, that we haven't implemented.
641 // (can't use the vtable because it is not guaranteed to be initialized yet)
642 InstanceKlass* super = klass->java_super();
643 while (super != NULL__null) {
644 for (int i = 0; i < super->methods()->length(); ++i) {
645 Method* m = super->methods()->at(i);
646 if (m->is_overpass() || m->is_static()) {
647 // m is a method that would have been a miranda if not for the
648 // default method processing that occurred on behalf of our superclass,
649 // so it's a method we want to re-examine in this new context. That is,
650 // unless we have a real implementation of it in the current class.
651 if (!already_in_vtable_slots(slots, m)) {
652 Method *impl = klass->lookup_method(m->name(), m->signature());
653 if (impl == NULL__null || impl->is_overpass() || impl->is_static()) {
654 slots->append(new EmptyVtableSlot(m));
655 }
656 }
657 }
658 }
659
660 // also any default methods in our superclasses
661 if (super->default_methods() != NULL__null) {
662 for (int i = 0; i < super->default_methods()->length(); ++i) {
663 Method* m = super->default_methods()->at(i);
664 // m is a method that would have been a miranda if not for the
665 // default method processing that occurred on behalf of our superclass,
666 // so it's a method we want to re-examine in this new context. That is,
667 // unless we have a real implementation of it in the current class.
668 if (!already_in_vtable_slots(slots, m)) {
669 Method* impl = klass->lookup_method(m->name(), m->signature());
670 if (impl == NULL__null || impl->is_overpass() || impl->is_static()) {
671 slots->append(new EmptyVtableSlot(m));
672 }
673 }
674 }
675 }
676 super = super->java_super();
677 }
678
679 LogTarget(Debug, defaultmethods)LogTargetImpl<LogLevel::Debug, (LogTag::_defaultmethods), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG)>
lt;
680 if (lt.is_enabled()) {
681 lt.print("Slots that need filling:");
682 ResourceMark rm;
683 LogStream ls(lt);
684 streamIndentor si(&ls);
685 for (int i = 0; i < slots->length(); ++i) {
686 ls.indent();
687 slots->at(i)->print_on(&ls);
688 ls.cr();
689 }
690 }
691}
692
693// Iterates over the superinterface type hierarchy looking for all methods
694// with a specific erased signature.
695class FindMethodsByErasedSig : public HierarchyVisitor<FindMethodsByErasedSig> {
696 private:
697 // Context data
698 Symbol* _method_name;
699 Symbol* _method_signature;
700 StatefulMethodFamily* _family;
701 bool _cur_class_is_interface;
702 // Free lists, used as an optimization
703 GrowableArray<StateRestorerScope*> _free_scopes;
704 GrowableArray<StateRestorer*> _free_restorers;
705 public:
706 FindMethodsByErasedSig() : _free_scopes(6), _free_restorers(6) {};
707
708 void prepare(Symbol* name, Symbol* signature, bool is_interf) {
709 reset();
710 _method_name = name;
711 _method_signature = signature;
712 _family = NULL__null;
713 _cur_class_is_interface = is_interf;
714 }
715
716 void get_discovered_family(MethodFamily** family) {
717 if (_family != NULL__null) {
718 *family = _family->get_method_family();
719 } else {
720 *family = NULL__null;
721 }
722 }
723
724 void* new_node_data() {
725 if (!_free_scopes.is_empty()) {
726 StateRestorerScope* free_scope = _free_scopes.pop();
727 assert(free_scope->is_empty(), "StateRestorerScope::_marks array not empty")do { if (!(free_scope->is_empty())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 727, "assert(" "free_scope->is_empty()" ") failed", "StateRestorerScope::_marks array not empty"
); ::breakpoint(); } } while (0)
;
728 return free_scope;
729 }
730 return new StateRestorerScope(&_free_restorers);
731 }
732 void free_node_data(void* node_data) {
733 StateRestorerScope* scope = StateRestorerScope::cast(node_data);
734 scope->restore_state();
735 // Reuse scopes
736 _free_scopes.push(scope);
737 }
738
739 // Find all methods on this hierarchy that match this
740 // method's erased (name, signature)
741 bool visit() {
742 StateRestorerScope* scope = StateRestorerScope::cast(current_data());
743 InstanceKlass* iklass = current_class();
744
745 Method* m = iklass->find_method(_method_name, _method_signature);
746 // Private interface methods are not candidates for default methods.
747 // invokespecial to private interface methods doesn't use default method logic.
748 // Private class methods are not candidates for default methods.
749 // Private methods do not override default methods, so need to perform
750 // default method inheritance without including private methods.
751 // The overpasses are your supertypes' errors, we do not include them.
752 // Non-public methods in java.lang.Object are not candidates for default
753 // methods.
754 // Future: take access controls into account for superclass methods
755 if (m != NULL__null && !m->is_static() && !m->is_overpass() && !m->is_private() &&
756 (!_cur_class_is_interface || !SystemDictionary::is_nonpublic_Object_method(m))) {
757 if (_family == NULL__null) {
758 _family = new StatefulMethodFamily();
759 }
760
761 if (iklass->is_interface()) {
762 _family->record_method_and_dq_further(scope, m);
763 } else {
764 // This is the rule that methods in classes "win" (bad word) over
765 // methods in interfaces. This works because of single inheritance.
766 // Private methods in classes do not "win", they will be found
767 // first on searching, but overriding for invokevirtual needs
768 // to find default method candidates for the same signature
769 _family->set_target_if_empty(m);
770 }
771 }
772 return true;
773 }
774
775};
776
777
778
779static void create_defaults_and_exceptions(
780 GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPSJavaThread* __the_thread__);
781
782static void generate_erased_defaults(
783 FindMethodsByErasedSig* visitor,
784 InstanceKlass* klass, EmptyVtableSlot* slot, bool is_intf) {
785
786 // the visitor needs to be initialized or re-initialized before use
787 // - this facilitates reusing the same visitor instance on multiple
788 // generation passes as an optimization
789 visitor->prepare(slot->name(), slot->signature(), is_intf);
790 // sets up a set of methods with the same exact erased signature
791 visitor->run(klass);
792
793 MethodFamily* family;
794 visitor->get_discovered_family(&family);
795 if (family != NULL__null) {
796 family->determine_target_or_set_exception_message(klass);
797 slot->bind_family(family);
798 }
799}
800
801static void merge_in_new_methods(InstanceKlass* klass,
802 GrowableArray<Method*>* new_methods, TRAPSJavaThread* __the_thread__);
803static void create_default_methods( InstanceKlass* klass,
804 GrowableArray<Method*>* new_methods, TRAPSJavaThread* __the_thread__);
805
806// This is the guts of the default methods implementation. This is called just
807// after the classfile has been parsed if some ancestor has default methods.
808//
809// First it finds any name/signature slots that need any implementation (either
810// because they are miranda or a superclass's implementation is an overpass
811// itself). For each slot, iterate over the hierarchy, to see if they contain a
812// signature that matches the slot we are looking at.
813//
814// For each slot filled, we either record the default method candidate in the
815// klass default_methods list or, only to handle exception cases, we create an
816// overpass method that throws an exception and add it to the klass methods list.
817// The JVM does not create bridges nor handle generic signatures here.
818void DefaultMethods::generate_default_methods(
819 InstanceKlass* klass, const GrowableArray<Method*>* mirandas, TRAPSJavaThread* __the_thread__) {
820 assert(klass != NULL, "invariant")do { if (!(klass != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 820, "assert(" "klass != __null" ") failed", "invariant"); ::
breakpoint(); } } while (0)
;
1
Assuming the condition is true
2
Taking false branch
3
Loop condition is false. Exiting loop
821 assert(klass != vmClasses::Object_klass(), "Shouldn't be called for Object")do { if (!(klass != vmClasses::Object_klass())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 821, "assert(" "klass != vmClasses::Object_klass()" ") failed"
, "Shouldn't be called for Object"); ::breakpoint(); } } while
(0)
;
4
Assuming the condition is true
5
Taking false branch
6
Loop condition is false. Exiting loop
822
823 // This resource mark is the bound for all memory allocation that takes
824 // place during default method processing. After this goes out of scope,
825 // all (Resource) objects' memory will be reclaimed. Be careful if adding an
826 // embedded resource mark under here as that memory can't be used outside
827 // whatever scope it's in.
828 ResourceMark rm(THREAD__the_thread__);
829
830 // Keep entire hierarchy alive for the duration of the computation
831 constantPoolHandle cp(THREAD__the_thread__, klass->constants());
832 KeepAliveRegistrar keepAlive(THREAD__the_thread__);
833 KeepAliveVisitor loadKeepAlive(&keepAlive);
834 loadKeepAlive.run(klass);
835
836 LogTarget(Debug, defaultmethods)LogTargetImpl<LogLevel::Debug, (LogTag::_defaultmethods), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG)>
lt;
837 if (lt.is_enabled()) {
7
Assuming the condition is false
8
Taking false branch
838 ResourceMark rm(THREAD__the_thread__);
839 lt.print("%s %s requires default method processing",
840 klass->is_interface() ? "Interface" : "Class",
841 klass->name()->as_klass_external_name());
842 LogStream ls(lt);
843 PrintHierarchy printer(&ls);
844 printer.run(klass);
845 }
846
847 GrowableArray<EmptyVtableSlot*> empty_slots;
848 find_empty_vtable_slots(&empty_slots, klass, mirandas);
849
850 if (empty_slots.length() > 0) {
9
Assuming the condition is true
10
Taking true branch
851 FindMethodsByErasedSig findMethodsByErasedSig;
852 for (int i = 0; i < empty_slots.length(); ++i) {
11
Loop condition is true. Entering loop body
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 864
853 EmptyVtableSlot* slot = empty_slots.at(i);
854 LogTarget(Debug, defaultmethods)LogTargetImpl<LogLevel::Debug, (LogTag::_defaultmethods), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG)>
lt;
855 if (lt.is_enabled()) {
12
Assuming the condition is false
13
Taking false branch
856 LogStream ls(lt);
857 streamIndentor si(&ls, 2);
858 ls.indent().print("Looking for default methods for slot ");
859 slot->print_on(&ls);
860 ls.cr();
861 }
862 generate_erased_defaults(&findMethodsByErasedSig, klass, slot, klass->is_interface());
863 }
864 log_debug(defaultmethods)(!(LogImpl<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl
<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::write<LogLevel::Debug>
("Creating defaults and overpasses...");
16
Assuming the condition is true
17
'?' condition is true
865 create_defaults_and_exceptions(&empty_slots, klass, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
18
Calling 'create_defaults_and_exceptions'
866 }
867 log_debug(defaultmethods)(!(LogImpl<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl
<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::write<LogLevel::Debug>
("Default method processing complete");
868}
869
870static int assemble_method_error(
871 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message) {
872
873 Symbol* init = vmSymbols::object_initializer_name();
874 Symbol* sig = vmSymbols::string_void_signature();
875
876 BytecodeAssembler assem(buffer, cp);
877
878 assem._new(errorName);
879 assem.dup();
880 assem.load_string(message);
881 assem.invokespecial(errorName, init, sig);
882 assem.athrow();
883
884 return 3; // max stack size: [ exception, exception, string ]
885}
886
887static Method* new_method(
888 BytecodeConstantPool* cp, BytecodeBuffer* bytecodes, Symbol* name,
889 Symbol* sig, AccessFlags flags, int max_stack, int params,
890 ConstMethod::MethodType mt, TRAPSJavaThread* __the_thread__) {
891
892 address code_start = 0;
28
'code_start' initialized to a null pointer value
893 int code_length = 0;
894 InlineTableSizes sizes;
895
896 if (bytecodes != NULL__null && bytecodes->length() > 0) {
29
Assuming 'bytecodes' is equal to NULL
897 code_start = static_cast<address>(bytecodes->adr_at(0));
898 code_length = bytecodes->length();
899 }
900
901 Method* m = Method::allocate(cp->pool_holder()->class_loader_data(),
902 code_length, flags, &sizes,
903 mt, CHECK_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
);
30
Calling 'ThreadShadow::has_pending_exception'
36
Returning from 'ThreadShadow::has_pending_exception'
37
Taking false branch
904
905 m->set_constants(NULL__null); // This will get filled in later
906 m->set_name_index(cp->utf8(name));
907 m->set_signature_index(cp->utf8(sig));
908 m->compute_from_signature(sig);
909 m->set_size_of_parameters(params);
910 m->set_max_stack(max_stack);
911 m->set_max_locals(params);
912 m->constMethod()->set_stackmap_data(NULL__null);
913 m->set_code(code_start);
38
Passing null pointer value via 1st parameter 'code'
39
Calling 'Method::set_code'
914
915 return m;
916}
917
918static void switchover_constant_pool(BytecodeConstantPool* bpool,
919 InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPSJavaThread* __the_thread__) {
920
921 if (new_methods->length() > 0) {
922 ConstantPool* cp = bpool->create_constant_pool(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
923 if (cp != klass->constants()) {
924 // Copy resolved hidden class into new constant pool.
925 if (klass->is_hidden()) {
926 cp->klass_at_put(klass->this_class_index(), klass);
927 }
928 klass->class_loader_data()->add_to_deallocate_list(klass->constants());
929 klass->set_constants(cp);
930 cp->set_pool_holder(klass);
931
932 for (int i = 0; i < new_methods->length(); ++i) {
933 new_methods->at(i)->set_constants(cp);
934 }
935 for (int i = 0; i < klass->methods()->length(); ++i) {
936 Method* mo = klass->methods()->at(i);
937 mo->set_constants(cp);
938 }
939 }
940 }
941}
942
943// Create default_methods list for the current class.
944// With the VM only processing erased signatures, the VM only
945// creates an overpass in a conflict case or a case with no candidates.
946// This allows virtual methods to override the overpass, but ensures
947// that a local method search will find the exception rather than an abstract
948// or default method that is not a valid candidate.
949//
950// Note that if overpass method are ever created that are not exception
951// throwing methods then the loader constraint checking logic for vtable and
952// itable creation needs to be changed to check loader constraints for the
953// overpass methods that do not throw exceptions.
954static void create_defaults_and_exceptions(GrowableArray<EmptyVtableSlot*>* slots,
955 InstanceKlass* klass, TRAPSJavaThread* __the_thread__) {
956
957 GrowableArray<Method*> overpasses;
958 GrowableArray<Method*> defaults;
959 BytecodeConstantPool bpool(klass->constants());
960
961 BytecodeBuffer* buffer = NULL__null; // Lazily create a reusable buffer
962 for (int i = 0; i < slots->length(); ++i) {
19
Assuming the condition is true
20
Loop condition is true. Entering loop body
963 EmptyVtableSlot* slot = slots->at(i);
964
965 if (slot->is_bound()) {
21
Taking true branch
966 MethodFamily* method = slot->get_binding();
967
968 LogTarget(Debug, defaultmethods)LogTargetImpl<LogLevel::Debug, (LogTag::_defaultmethods), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG)>
lt;
969 if (lt.is_enabled()) {
22
Assuming the condition is false
23
Taking false branch
970 ResourceMark rm(THREAD__the_thread__);
971 LogStream ls(lt);
972 ls.print("for slot: ");
973 slot->print_on(&ls);
974 ls.cr();
975 if (method->has_target()) {
976 method->print_selected(&ls, 1);
977 } else if (method->throws_exception()) {
978 method->print_exception(&ls, 1);
979 }
980 }
981
982 if (method->has_target()) {
24
Taking false branch
983 Method* selected = method->get_selected_target();
984 if (selected->method_holder()->is_interface()) {
985 assert(!selected->is_private(), "pushing private interface method as default")do { if (!(!selected->is_private())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 985, "assert(" "!selected->is_private()" ") failed", "pushing private interface method as default"
); ::breakpoint(); } } while (0)
;
986 defaults.push(selected);
987 }
988 } else if (method->throws_exception()) {
25
Taking true branch
989 if (buffer
25.1
'buffer' is equal to NULL
25.1
'buffer' is equal to NULL
25.1
'buffer' is equal to NULL
25.1
'buffer' is equal to NULL
25.1
'buffer' is equal to NULL
== NULL__null) {
26
Taking true branch
990 buffer = new BytecodeBuffer();
991 } else {
992 buffer->clear();
993 }
994 int max_stack = assemble_method_error(&bpool, buffer,
995 method->get_exception_name(), method->get_exception_message());
996 AccessFlags flags = accessFlags_from(
997 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE);
998 Method* m = new_method(&bpool, buffer, slot->name(), slot->signature(),
27
Calling 'new_method'
999 flags, max_stack, slot->size_of_parameters(),
1000 ConstMethod::OVERPASS, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1001 // We push to the methods list:
1002 // overpass methods which are exception throwing methods
1003 if (m != NULL__null) {
1004 overpasses.push(m);
1005 }
1006 }
1007 }
1008 }
1009
1010
1011 log_debug(defaultmethods)(!(LogImpl<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl
<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::write<LogLevel::Debug>
("Created %d overpass methods", overpasses.length());
1012 log_debug(defaultmethods)(!(LogImpl<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (
LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag
::__NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl
<(LogTag::_defaultmethods), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::write<LogLevel::Debug>
("Created %d default methods", defaults.length());
1013
1014 if (overpasses.length() > 0) {
1015 switchover_constant_pool(&bpool, klass, &overpasses, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1016 merge_in_new_methods(klass, &overpasses, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1017 }
1018 if (defaults.length() > 0) {
1019 create_default_methods(klass, &defaults, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1020 }
1021}
1022
1023static void create_default_methods(InstanceKlass* klass,
1024 GrowableArray<Method*>* new_methods, TRAPSJavaThread* __the_thread__) {
1025
1026 int new_size = new_methods->length();
1027 Array<Method*>* total_default_methods = MetadataFactory::new_array<Method*>(
1028 klass->class_loader_data(), new_size, NULL__null, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1029 for (int index = 0; index < new_size; index++ ) {
1030 total_default_methods->at_put(index, new_methods->at(index));
1031 }
1032 Method::sort_methods(total_default_methods, /*set_idnums=*/false);
1033
1034 klass->set_default_methods(total_default_methods);
1035 // Create an array for mapping default methods to their vtable indices in
1036 // this class, since default methods vtable indices are the indices for
1037 // the defining class.
1038 klass->create_new_default_vtable_indices(new_size, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1039}
1040
1041static void sort_methods(GrowableArray<Method*>* methods) {
1042 // Note that this must sort using the same key as is used for sorting
1043 // methods in InstanceKlass.
1044 bool sorted = true;
1045 for (int i = methods->length() - 1; i > 0; --i) {
1046 for (int j = 0; j < i; ++j) {
1047 Method* m1 = methods->at(j);
1048 Method* m2 = methods->at(j + 1);
1049 if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) {
1050 methods->at_put(j, m2);
1051 methods->at_put(j + 1, m1);
1052 sorted = false;
1053 }
1054 }
1055 if (sorted) break;
1056 sorted = true;
1057 }
1058#ifdef ASSERT1
1059 uintptr_t prev = 0;
1060 for (int i = 0; i < methods->length(); ++i) {
1061 Method* mh = methods->at(i);
1062 uintptr_t nv = (uintptr_t)mh->name();
1063 assert(nv >= prev, "Incorrect overpass method ordering")do { if (!(nv >= prev)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 1063, "assert(" "nv >= prev" ") failed", "Incorrect overpass method ordering"
); ::breakpoint(); } } while (0)
;
1064 prev = nv;
1065 }
1066#endif
1067}
1068
1069static void merge_in_new_methods(InstanceKlass* klass,
1070 GrowableArray<Method*>* new_methods, TRAPSJavaThread* __the_thread__) {
1071
1072 enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS };
1073
1074 Array<Method*>* original_methods = klass->methods();
1075 Array<int>* original_ordering = klass->method_ordering();
1076 Array<int>* merged_ordering = Universe::the_empty_int_array();
1077
1078 int new_size = klass->methods()->length() + new_methods->length();
1079
1080 Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>(
1081 klass->class_loader_data(), new_size, NULL__null, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1082
1083 // original_ordering might be empty if this class has no methods of its own
1084 if (JvmtiExport::can_maintain_original_method_order() || Arguments::is_dumping_archive()) {
1085 merged_ordering = MetadataFactory::new_array<int>(
1086 klass->class_loader_data(), new_size, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
1087 }
1088 int method_order_index = klass->methods()->length();
1089
1090 sort_methods(new_methods);
1091
1092 // Perform grand merge of existing methods and new methods
1093 int orig_idx = 0;
1094 int new_idx = 0;
1095
1096 for (int i = 0; i < new_size; ++i) {
1097 Method* orig_method = NULL__null;
1098 Method* new_method = NULL__null;
1099 if (orig_idx < original_methods->length()) {
1100 orig_method = original_methods->at(orig_idx);
1101 }
1102 if (new_idx < new_methods->length()) {
1103 new_method = new_methods->at(new_idx);
1104 }
1105
1106 if (orig_method != NULL__null &&
1107 (new_method == NULL__null || orig_method->name() < new_method->name())) {
1108 merged_methods->at_put(i, orig_method);
1109 original_methods->at_put(orig_idx, NULL__null);
1110 if (merged_ordering->length() > 0) {
1111 assert(original_ordering != NULL && original_ordering->length() > 0,do { if (!(original_ordering != __null && original_ordering
->length() > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 1112, "assert(" "original_ordering != __null && original_ordering->length() > 0"
") failed", "should have original order information for this method"
); ::breakpoint(); } } while (0)
1112 "should have original order information for this method")do { if (!(original_ordering != __null && original_ordering
->length() > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 1112, "assert(" "original_ordering != __null && original_ordering->length() > 0"
") failed", "should have original order information for this method"
); ::breakpoint(); } } while (0)
;
1113 merged_ordering->at_put(i, original_ordering->at(orig_idx));
1114 }
1115 ++orig_idx;
1116 } else {
1117 merged_methods->at_put(i, new_method);
1118 if (merged_ordering->length() > 0) {
1119 merged_ordering->at_put(i, method_order_index++);
1120 }
1121 ++new_idx;
1122 }
1123 // update idnum for new location
1124 merged_methods->at(i)->set_method_idnum(i);
1125 merged_methods->at(i)->set_orig_method_idnum(i);
1126 }
1127
1128 // Verify correct order
1129#ifdef ASSERT1
1130 uintptr_t prev = 0;
1131 for (int i = 0; i < merged_methods->length(); ++i) {
1132 Method* mo = merged_methods->at(i);
1133 uintptr_t nv = (uintptr_t)mo->name();
1134 assert(nv >= prev, "Incorrect method ordering")do { if (!(nv >= prev)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/defaultMethods.cpp"
, 1134, "assert(" "nv >= prev" ") failed", "Incorrect method ordering"
); ::breakpoint(); } } while (0)
;
1135 prev = nv;
1136 }
1137#endif
1138
1139 // Replace klass methods with new merged lists
1140 klass->set_methods(merged_methods);
1141 klass->set_initial_method_idnum(new_size);
1142 klass->set_method_ordering(merged_ordering);
1143
1144 // Free metadata
1145 ClassLoaderData* cld = klass->class_loader_data();
1146 if (original_methods->length() > 0) {
1147 MetadataFactory::free_array(cld, original_methods);
1148 }
1149 if (original_ordering != NULL__null && original_ordering->length() > 0) {
1150 MetadataFactory::free_array(cld, original_ordering);
1151 }
1152}

/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; }
31
Calling 'oop::operator!='
34
Returning from 'oop::operator!='
35
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; }
32
Assuming the condition is false
33
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

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

1/*
2 * Copyright (c) 1997, 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_OOPS_METHOD_HPP
26#define SHARE_OOPS_METHOD_HPP
27
28#include "code/compressedStream.hpp"
29#include "compiler/compilerDefinitions.hpp"
30#include "interpreter/invocationCounter.hpp"
31#include "oops/annotations.hpp"
32#include "oops/constantPool.hpp"
33#include "oops/methodCounters.hpp"
34#include "oops/instanceKlass.hpp"
35#include "oops/oop.hpp"
36#include "oops/typeArrayOop.hpp"
37#include "utilities/accessFlags.hpp"
38#include "utilities/align.hpp"
39#include "utilities/growableArray.hpp"
40#include "utilities/macros.hpp"
41#include "utilities/vmEnums.hpp"
42#if INCLUDE_JFR1
43#include "jfr/support/jfrTraceIdExtension.hpp"
44#endif
45
46
47// A Method represents a Java method.
48//
49// Note that most applications load thousands of methods, so keeping the size of this
50// class small has a big impact on footprint.
51//
52// Note that native_function and signature_handler have to be at fixed offsets
53// (required by the interpreter)
54//
55// Method embedded field layout (after declared fields):
56// [EMBEDDED native_function (present only if native) ]
57// [EMBEDDED signature_handler (present only if native) ]
58
59class CheckedExceptionElement;
60class LocalVariableTableElement;
61class AdapterHandlerEntry;
62class MethodData;
63class MethodCounters;
64class ConstMethod;
65class InlineTableSizes;
66class CompiledMethod;
67class InterpreterOopMap;
68
69class Method : public Metadata {
70 friend class VMStructs;
71 friend class JVMCIVMStructs;
72 private:
73 // If you add a new field that points to any metaspace object, you
74 // must add this field to Method::metaspace_pointers_do().
75 ConstMethod* _constMethod; // Method read-only data.
76 MethodData* _method_data;
77 MethodCounters* _method_counters;
78 AdapterHandlerEntry* _adapter;
79 AccessFlags _access_flags; // Access flags
80 int _vtable_index; // vtable index of this method (see VtableIndexFlag)
81 // note: can have vtables with >2**16 elements (because of inheritance)
82 u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
83
84 // Flags
85 enum Flags {
86 _caller_sensitive = 1 << 0,
87 _force_inline = 1 << 1,
88 _dont_inline = 1 << 2,
89 _hidden = 1 << 3,
90 _has_injected_profile = 1 << 4,
91 _intrinsic_candidate = 1 << 5,
92 _reserved_stack_access = 1 << 6,
93 _scoped = 1 << 7
94 };
95 mutable u2 _flags;
96
97 JFR_ONLY(DEFINE_TRACE_FLAG;)mutable JfrTraceFlag _trace_flags;
98
99#ifndef PRODUCT
100 int64_t _compiled_invocation_count;
101#endif
102 // Entry point for calling both from and to the interpreter.
103 address _i2i_entry; // All-args-on-stack calling convention
104 // Entry point for calling from compiled code, to compiled code if it exists
105 // or else the interpreter.
106 volatile address _from_compiled_entry; // Cache of: _code ? _code->entry_point() : _adapter->c2i_entry()
107 // The entry point for calling both from and to compiled code is
108 // "_code->entry_point()". Because of tiered compilation and de-opt, this
109 // field can come and go. It can transition from NULL to not-null at any
110 // time (whenever a compile completes). It can transition from not-null to
111 // NULL only at safepoints (because of a de-opt).
112 CompiledMethod* volatile _code; // Points to the corresponding piece of native code
113 volatile address _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry
114
115 // Constructor
116 Method(ConstMethod* xconst, AccessFlags access_flags);
117 public:
118
119 static Method* allocate(ClassLoaderData* loader_data,
120 int byte_code_size,
121 AccessFlags access_flags,
122 InlineTableSizes* sizes,
123 ConstMethod::MethodType method_type,
124 TRAPSJavaThread* __the_thread__);
125
126 // CDS and vtbl checking can create an empty Method to get vtbl pointer.
127 Method(){}
128
129 virtual bool is_method() const { return true; }
130
131 void restore_unshareable_info(TRAPSJavaThread* __the_thread__);
132
133 // accessors for instance variables
134
135 ConstMethod* constMethod() const { return _constMethod; }
136 void set_constMethod(ConstMethod* xconst) { _constMethod = xconst; }
137
138
139 static address make_adapters(const methodHandle& mh, TRAPSJavaThread* __the_thread__);
140 address from_compiled_entry() const;
141 address from_compiled_entry_no_trampoline() const;
142 address from_interpreted_entry() const;
143
144 // access flag
145 AccessFlags access_flags() const { return _access_flags; }
146 void set_access_flags(AccessFlags flags) { _access_flags = flags; }
147
148 // name
149 Symbol* name() const { return constants()->symbol_at(name_index()); }
150 int name_index() const { return constMethod()->name_index(); }
151 void set_name_index(int index) { constMethod()->set_name_index(index); }
152
153 // signature
154 Symbol* signature() const { return constants()->symbol_at(signature_index()); }
155 int signature_index() const { return constMethod()->signature_index(); }
156 void set_signature_index(int index) { constMethod()->set_signature_index(index); }
157
158 // generics support
159 Symbol* generic_signature() const { int idx = generic_signature_index(); return ((idx != 0) ? constants()->symbol_at(idx) : (Symbol*)NULL__null); }
160 int generic_signature_index() const { return constMethod()->generic_signature_index(); }
161 void set_generic_signature_index(int index) { constMethod()->set_generic_signature_index(index); }
162
163 // annotations support
164 AnnotationArray* annotations() const {
165 return constMethod()->method_annotations();
166 }
167 AnnotationArray* parameter_annotations() const {
168 return constMethod()->parameter_annotations();
169 }
170 AnnotationArray* annotation_default() const {
171 return constMethod()->default_annotations();
172 }
173 AnnotationArray* type_annotations() const {
174 return constMethod()->type_annotations();
175 }
176
177 // Helper routine: get klass name + "." + method name + signature as
178 // C string, for the purpose of providing more useful
179 // fatal error handling. The string is allocated in resource
180 // area if a buffer is not provided by the caller.
181 char* name_and_sig_as_C_string() const;
182 char* name_and_sig_as_C_string(char* buf, int size) const;
183
184 // Static routine in the situations we don't have a Method*
185 static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature);
186 static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size);
187
188 // Get return type + klass name + "." + method name + ( parameters types )
189 // as a C string or print it to an outputStream.
190 // This is to be used to assemble strings passed to Java, so that
191 // the text more resembles Java code. Used in exception messages.
192 // Memory is allocated in the resource area; the caller needs
193 // a ResourceMark.
194 const char* external_name() const;
195 void print_external_name(outputStream *os) const;
196
197 static const char* external_name( Klass* klass, Symbol* method_name, Symbol* signature);
198 static void print_external_name(outputStream *os, Klass* klass, Symbol* method_name, Symbol* signature);
199
200 Bytecodes::Code java_code_at(int bci) const {
201 return Bytecodes::java_code_at(this, bcp_from(bci));
202 }
203 Bytecodes::Code code_at(int bci) const {
204 return Bytecodes::code_at(this, bcp_from(bci));
205 }
206
207 // JVMTI breakpoints
208#if !INCLUDE_JVMTI1
209 Bytecodes::Code orig_bytecode_at(int bci) const {
210 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 210); ::breakpoint(); } while (0)
;
211 return Bytecodes::_shouldnotreachhere;
212 }
213 void set_orig_bytecode_at(int bci, Bytecodes::Code code) {
214 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 214); ::breakpoint(); } while (0)
;
215 };
216 u2 number_of_breakpoints() const {return 0;}
217#else // !INCLUDE_JVMTI
218 Bytecodes::Code orig_bytecode_at(int bci) const;
219 void set_orig_bytecode_at(int bci, Bytecodes::Code code);
220 void set_breakpoint(int bci);
221 void clear_breakpoint(int bci);
222 void clear_all_breakpoints();
223 // Tracking number of breakpoints, for fullspeed debugging.
224 // Only mutated by VM thread.
225 u2 number_of_breakpoints() const {
226 MethodCounters* mcs = method_counters();
227 if (mcs == NULL__null) {
228 return 0;
229 } else {
230 return mcs->number_of_breakpoints();
231 }
232 }
233 void incr_number_of_breakpoints(Thread* current) {
234 MethodCounters* mcs = get_method_counters(current);
235 if (mcs != NULL__null) {
236 mcs->incr_number_of_breakpoints();
237 }
238 }
239 void decr_number_of_breakpoints(Thread* current) {
240 MethodCounters* mcs = get_method_counters(current);
241 if (mcs != NULL__null) {
242 mcs->decr_number_of_breakpoints();
243 }
244 }
245 // Initialization only
246 void clear_number_of_breakpoints() {
247 MethodCounters* mcs = method_counters();
248 if (mcs != NULL__null) {
249 mcs->clear_number_of_breakpoints();
250 }
251 }
252#endif // !INCLUDE_JVMTI
253
254 // index into InstanceKlass methods() array
255 // note: also used by jfr
256 u2 method_idnum() const { return constMethod()->method_idnum(); }
257 void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); }
258
259 u2 orig_method_idnum() const { return constMethod()->orig_method_idnum(); }
260 void set_orig_method_idnum(u2 idnum) { constMethod()->set_orig_method_idnum(idnum); }
261
262 // code size
263 int code_size() const { return constMethod()->code_size(); }
264
265 // method size in words
266 int method_size() const { return sizeof(Method)/wordSize + ( is_native() ? 2 : 0 ); }
267
268 // constant pool for Klass* holding this method
269 ConstantPool* constants() const { return constMethod()->constants(); }
270 void set_constants(ConstantPool* c) { constMethod()->set_constants(c); }
271
272 // max stack
273 // return original max stack size for method verification
274 int verifier_max_stack() const { return constMethod()->max_stack(); }
275 int max_stack() const { return constMethod()->max_stack() + extra_stack_entries(); }
276 void set_max_stack(int size) { constMethod()->set_max_stack(size); }
277
278 // max locals
279 int max_locals() const { return constMethod()->max_locals(); }
280 void set_max_locals(int size) { constMethod()->set_max_locals(size); }
281
282 int highest_comp_level() const;
283 void set_highest_comp_level(int level);
284 int highest_osr_comp_level() const;
285 void set_highest_osr_comp_level(int level);
286
287#if COMPILER2_OR_JVMCI1
288 // Count of times method was exited via exception while interpreting
289 void interpreter_throwout_increment(Thread* current) {
290 MethodCounters* mcs = get_method_counters(current);
291 if (mcs != NULL__null) {
292 mcs->interpreter_throwout_increment();
293 }
294 }
295#endif
296
297 int interpreter_throwout_count() const {
298 MethodCounters* mcs = method_counters();
299 if (mcs == NULL__null) {
300 return 0;
301 } else {
302 return mcs->interpreter_throwout_count();
303 }
304 }
305
306 // Derive stuff from the signature at load time.
307 void compute_from_signature(Symbol* sig);
308
309 // size of parameters (receiver if any + arguments)
310 int size_of_parameters() const { return constMethod()->size_of_parameters(); }
311 void set_size_of_parameters(int size) { constMethod()->set_size_of_parameters(size); }
312
313 bool has_stackmap_table() const {
314 return constMethod()->has_stackmap_table();
315 }
316
317 Array<u1>* stackmap_data() const {
318 return constMethod()->stackmap_data();
319 }
320
321 void set_stackmap_data(Array<u1>* sd) {
322 constMethod()->set_stackmap_data(sd);
323 }
324
325 // exception handler table
326 bool has_exception_handler() const
327 { return constMethod()->has_exception_handler(); }
328 int exception_table_length() const
329 { return constMethod()->exception_table_length(); }
330 ExceptionTableElement* exception_table_start() const
331 { return constMethod()->exception_table_start(); }
332
333 // Finds the first entry point bci of an exception handler for an
334 // exception of klass ex_klass thrown at throw_bci. A value of NULL
335 // for ex_klass indicates that the exception klass is not known; in
336 // this case it matches any constraint class. Returns -1 if the
337 // exception cannot be handled in this method. The handler
338 // constraint classes are loaded if necessary. Note that this may
339 // throw an exception if loading of the constraint classes causes
340 // an IllegalAccessError (bugid 4307310) or an OutOfMemoryError.
341 // If an exception is thrown, returns the bci of the
342 // exception handler which caused the exception to be thrown, which
343 // is needed for proper retries. See, for example,
344 // InterpreterRuntime::exception_handler_for_exception.
345 static int fast_exception_handler_bci_for(const methodHandle& mh, Klass* ex_klass, int throw_bci, TRAPSJavaThread* __the_thread__);
346
347 static bool register_native(Klass* k,
348 Symbol* name,
349 Symbol* signature,
350 address entry,
351 TRAPSJavaThread* __the_thread__);
352
353 // method data access
354 MethodData* method_data() const {
355 return _method_data;
356 }
357
358 void set_method_data(MethodData* data);
359
360 MethodCounters* method_counters() const {
361 return _method_counters;
362 }
363
364 void clear_method_counters() {
365 _method_counters = NULL__null;
366 }
367
368 bool init_method_counters(MethodCounters* counters);
369
370 int prev_event_count() const {
371 MethodCounters* mcs = method_counters();
372 return mcs == NULL__null ? 0 : mcs->prev_event_count();
373 }
374 void set_prev_event_count(int count) {
375 MethodCounters* mcs = method_counters();
376 if (mcs != NULL__null) {
377 mcs->set_prev_event_count(count);
378 }
379 }
380 jlong prev_time() const {
381 MethodCounters* mcs = method_counters();
382 return mcs == NULL__null ? 0 : mcs->prev_time();
383 }
384 void set_prev_time(jlong time) {
385 MethodCounters* mcs = method_counters();
386 if (mcs != NULL__null) {
387 mcs->set_prev_time(time);
388 }
389 }
390 float rate() const {
391 MethodCounters* mcs = method_counters();
392 return mcs == NULL__null ? 0 : mcs->rate();
393 }
394 void set_rate(float rate) {
395 MethodCounters* mcs = method_counters();
396 if (mcs != NULL__null) {
397 mcs->set_rate(rate);
398 }
399 }
400
401 int nmethod_age() const {
402 if (method_counters() == NULL__null) {
403 return INT_MAX2147483647;
404 } else {
405 return method_counters()->nmethod_age();
406 }
407 }
408
409 int invocation_count() const;
410 int backedge_count() const;
411
412 bool was_executed_more_than(int n);
413 bool was_never_executed() { return !was_executed_more_than(0); }
414
415 static void build_interpreter_method_data(const methodHandle& method, TRAPSJavaThread* __the_thread__);
416
417 static MethodCounters* build_method_counters(Thread* current, Method* m);
418
419 int interpreter_invocation_count() { return invocation_count(); }
420
421#ifndef PRODUCT
422 int64_t compiled_invocation_count() const { return _compiled_invocation_count;}
423 void set_compiled_invocation_count(int count) { _compiled_invocation_count = (int64_t)count; }
424#else
425 // for PrintMethodData in a product build
426 int64_t compiled_invocation_count() const { return 0; }
427#endif // not PRODUCT
428
429 // Clear (non-shared space) pointers which could not be relevant
430 // if this (shared) method were mapped into another JVM.
431 void remove_unshareable_info();
432
433 // nmethod/verified compiler entry
434 address verified_code_entry();
435 bool check_code() const; // Not inline to avoid circular ref
436 CompiledMethod* volatile code() const;
437
438 // Locks CompiledMethod_lock if not held.
439 void unlink_code(CompiledMethod *compare);
440 // Locks CompiledMethod_lock if not held.
441 void unlink_code();
442
443private:
444 // Either called with CompiledMethod_lock held or from constructor.
445 void clear_code();
446
447public:
448 static void set_code(const methodHandle& mh, CompiledMethod* code);
449 void set_adapter_entry(AdapterHandlerEntry* adapter) {
450 _adapter = adapter;
451 }
452 void set_from_compiled_entry(address entry) {
453 _from_compiled_entry = entry;
454 }
455
456 address get_i2c_entry();
457 address get_c2i_entry();
458 address get_c2i_unverified_entry();
459 address get_c2i_no_clinit_check_entry();
460 AdapterHandlerEntry* adapter() const {
461 return _adapter;
462 }
463 // setup entry points
464 void link_method(const methodHandle& method, TRAPSJavaThread* __the_thread__);
465 // clear entry points. Used by sharing code during dump time
466 void unlink_method() NOT_CDS_RETURN;
467
468 virtual void metaspace_pointers_do(MetaspaceClosure* iter);
469 virtual MetaspaceObj::Type type() const { return MethodType; }
470
471 // vtable index
472 enum VtableIndexFlag {
473 // Valid vtable indexes are non-negative (>= 0).
474 // These few negative values are used as sentinels.
475 itable_index_max = -10, // first itable index, growing downward
476 pending_itable_index = -9, // itable index will be assigned
477 invalid_vtable_index = -4, // distinct from any valid vtable index
478 garbage_vtable_index = -3, // not yet linked; no vtable layout yet
479 nonvirtual_vtable_index = -2 // there is no need for vtable dispatch
480 // 6330203 Note: Do not use -1, which was overloaded with many meanings.
481 };
482 DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; })bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index
; }
483 bool has_vtable_index() const { return _vtable_index >= 0; }
484 int vtable_index() const { return _vtable_index; }
485 void set_vtable_index(int index);
486 DEBUG_ONLY(bool valid_itable_index() const { return _vtable_index <= pending_itable_index; })bool valid_itable_index() const { return _vtable_index <= pending_itable_index
; }
487 bool has_itable_index() const { return _vtable_index <= itable_index_max; }
488 int itable_index() const { assert(valid_itable_index(), "")do { if (!(valid_itable_index())) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 488, "assert(" "valid_itable_index()" ") failed", ""); ::breakpoint
(); } } while (0)
;
489 return itable_index_max - _vtable_index; }
490 void set_itable_index(int index);
491
492 // interpreter entry
493 address interpreter_entry() const { return _i2i_entry; }
494 // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
495 void set_interpreter_entry(address entry) {
496 if (_i2i_entry != entry) {
497 _i2i_entry = entry;
498 }
499 if (_from_interpreted_entry != entry) {
500 _from_interpreted_entry = entry;
501 }
502 }
503
504 // native function (used for native methods only)
505 enum {
506 native_bind_event_is_interesting = true
507 };
508 address native_function() const { return *(native_function_addr()); }
509
510 // Must specify a real function (not NULL).
511 // Use clear_native_function() to unregister.
512 void set_native_function(address function, bool post_event_flag);
513 bool has_native_function() const;
514 void clear_native_function();
515
516 // signature handler (used for native methods only)
517 address signature_handler() const { return *(signature_handler_addr()); }
518 void set_signature_handler(address handler);
519
520 // Interpreter oopmap support
521 void mask_for(int bci, InterpreterOopMap* mask);
522
523 // operations on invocation counter
524 void print_invocation_count();
525
526 // byte codes
527 void set_code(address code) { return constMethod()->set_code(code); }
40
Passing null pointer value via 1st parameter 'code'
41
Calling 'ConstMethod::set_code'
528 address code_base() const { return constMethod()->code_base(); }
529 bool contains(address bcp) const { return constMethod()->contains(bcp); }
530
531 // prints byte codes
532 void print_codes() const { print_codes_on(tty); }
533 void print_codes_on(outputStream* st) const;
534 void print_codes_on(int from, int to, outputStream* st) const;
535
536 // method parameters
537 bool has_method_parameters() const
538 { return constMethod()->has_method_parameters(); }
539 int method_parameters_length() const
540 { return constMethod()->method_parameters_length(); }
541 MethodParametersElement* method_parameters_start() const
542 { return constMethod()->method_parameters_start(); }
543
544 // checked exceptions
545 int checked_exceptions_length() const
546 { return constMethod()->checked_exceptions_length(); }
547 CheckedExceptionElement* checked_exceptions_start() const
548 { return constMethod()->checked_exceptions_start(); }
549
550 // localvariable table
551 bool has_localvariable_table() const
552 { return constMethod()->has_localvariable_table(); }
553 int localvariable_table_length() const
554 { return constMethod()->localvariable_table_length(); }
555 LocalVariableTableElement* localvariable_table_start() const
556 { return constMethod()->localvariable_table_start(); }
557
558 bool has_linenumber_table() const
559 { return constMethod()->has_linenumber_table(); }
560 u_char* compressed_linenumber_table() const
561 { return constMethod()->compressed_linenumber_table(); }
562
563 // method holder (the Klass* holding this method)
564 InstanceKlass* method_holder() const { return constants()->pool_holder(); }
565
566 Symbol* klass_name() const; // returns the name of the method holder
567 BasicType result_type() const { return constMethod()->result_type(); }
568 bool is_returning_oop() const { BasicType r = result_type(); return is_reference_type(r); }
569 bool is_returning_fp() const { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); }
570
571 // Checked exceptions thrown by this method (resolved to mirrors)
572 objArrayHandle resolved_checked_exceptions(TRAPSJavaThread* __the_thread__) { return resolved_checked_exceptions_impl(this, THREAD__the_thread__); }
573
574 // Access flags
575 bool is_public() const { return access_flags().is_public(); }
576 bool is_private() const { return access_flags().is_private(); }
577 bool is_protected() const { return access_flags().is_protected(); }
578 bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); }
579 bool is_static() const { return access_flags().is_static(); }
580 bool is_final() const { return access_flags().is_final(); }
581 bool is_synchronized() const { return access_flags().is_synchronized();}
582 bool is_native() const { return access_flags().is_native(); }
583 bool is_abstract() const { return access_flags().is_abstract(); }
584 bool is_synthetic() const { return access_flags().is_synthetic(); }
585
586 // returns true if contains only return operation
587 bool is_empty_method() const;
588
589 // returns true if this is a vanilla constructor
590 bool is_vanilla_constructor() const;
591
592 // checks method and its method holder
593 bool is_final_method() const;
594 bool is_final_method(AccessFlags class_access_flags) const;
595 // interface method declared with 'default' - excludes private interface methods
596 bool is_default_method() const;
597
598 // true if method needs no dynamic dispatch (final and/or no vtable entry)
599 bool can_be_statically_bound() const;
600 bool can_be_statically_bound(InstanceKlass* context) const;
601 bool can_be_statically_bound(AccessFlags class_access_flags) const;
602
603 // true if method can omit stack trace in throw in compiled code.
604 bool can_omit_stack_trace();
605
606 // returns true if the method has any backward branches.
607 bool has_loops() {
608 return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag();
609 };
610
611 bool compute_has_loops_flag();
612
613 bool has_jsrs() {
614 return access_flags().has_jsrs();
615 };
616 void set_has_jsrs() {
617 _access_flags.set_has_jsrs();
618 }
619
620 // returns true if the method has any monitors.
621 bool has_monitors() const { return is_synchronized() || access_flags().has_monitor_bytecodes(); }
622 bool has_monitor_bytecodes() const { return access_flags().has_monitor_bytecodes(); }
623
624 void set_has_monitor_bytecodes() { _access_flags.set_has_monitor_bytecodes(); }
625
626 // monitor matching. This returns a conservative estimate of whether the monitorenter/monitorexit bytecodes
627 // propererly nest in the method. It might return false, even though they actually nest properly, since the info.
628 // has not been computed yet.
629 bool guaranteed_monitor_matching() const { return access_flags().is_monitor_matching(); }
630 void set_guaranteed_monitor_matching() { _access_flags.set_monitor_matching(); }
631
632 // returns true if the method is an accessor function (setter/getter).
633 bool is_accessor() const;
634
635 // returns true if the method is a getter
636 bool is_getter() const;
637
638 // returns true if the method is a setter
639 bool is_setter() const;
640
641 // returns true if the method does nothing but return a constant of primitive type
642 bool is_constant_getter() const;
643
644 // returns true if the method is an initializer (<init> or <clinit>).
645 bool is_initializer() const;
646
647 // returns true if the method is static OR if the classfile version < 51
648 bool has_valid_initializer_flags() const;
649
650 // returns true if the method name is <clinit> and the method has
651 // valid static initializer flags.
652 bool is_static_initializer() const;
653
654 // returns true if the method name is <init>
655 bool is_object_initializer() const;
656
657 // compiled code support
658 // NOTE: code() is inherently racy as deopt can be clearing code
659 // simultaneously. Use with caution.
660 bool has_compiled_code() const;
661
662 bool needs_clinit_barrier() const;
663
664 // sizing
665 static int header_size() {
666 return align_up((int)sizeof(Method), wordSize) / wordSize;
667 }
668 static int size(bool is_native);
669 int size() const { return method_size(); }
670 void log_touched(Thread* current);
671 static void print_touched_methods(outputStream* out);
672
673 // interpreter support
674 static ByteSize const_offset() { return byte_offset_of(Method, _constMethod )in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_constMethod
) - 16))
; }
675 static ByteSize access_flags_offset() { return byte_offset_of(Method, _access_flags )in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_access_flags
) - 16))
; }
676 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry)in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_from_compiled_entry
) - 16))
; }
677 static ByteSize code_offset() { return byte_offset_of(Method, _code)in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_code
) - 16))
; }
678 static ByteSize method_data_offset() {
679 return byte_offset_of(Method, _method_data)in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_method_data
) - 16))
;
680 }
681 static ByteSize method_counters_offset() {
682 return byte_offset_of(Method, _method_counters)in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_method_counters
) - 16))
;
683 }
684#ifndef PRODUCT
685 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count)in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_compiled_invocation_count
) - 16))
; }
686#endif // not PRODUCT
687 static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); }
688 static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry )in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_from_interpreted_entry
) - 16))
; }
689 static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry )in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_i2i_entry
) - 16))
; }
690 static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); }
691 static ByteSize itable_index_offset() { return byte_offset_of(Method, _vtable_index )in_ByteSize((int)(size_t)((intx)&(((Method*)16)->_vtable_index
) - 16))
; }
692
693 // for code generation
694 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data)(size_t)((intx)&(((Method*)16)->_method_data) - 16); }
695 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id)(size_t)((intx)&(((Method*)16)->_intrinsic_id) - 16); }
696 static int intrinsic_id_size_in_bytes() { return sizeof(u2); }
697
698 // Static methods that are used to implement member methods where an exposed this pointer
699 // is needed due to possible GCs
700 static objArrayHandle resolved_checked_exceptions_impl(Method* method, TRAPSJavaThread* __the_thread__);
701
702 // Returns the byte code index from the byte code pointer
703 int bci_from(address bcp) const;
704 address bcp_from(int bci) const;
705 address bcp_from(address bcp) const;
706 int validate_bci_from_bcp(address bcp) const;
707 int validate_bci(int bci) const;
708
709 // Returns the line number for a bci if debugging information for the method is prowided,
710 // -1 is returned otherwise.
711 int line_number_from_bci(int bci) const;
712
713 // Reflection support
714 bool is_overridden_in(Klass* k) const;
715
716 // Stack walking support
717 bool is_ignored_by_security_stack_walk() const;
718
719 // JSR 292 support
720 bool is_method_handle_intrinsic() const; // MethodHandles::is_signature_polymorphic_intrinsic(intrinsic_id)
721 bool is_compiled_lambda_form() const; // intrinsic_id() == vmIntrinsics::_compiledLambdaForm
722 bool has_member_arg() const; // intrinsic_id() == vmIntrinsics::_linkToSpecial, etc.
723 static methodHandle make_method_handle_intrinsic(vmIntrinsicID iid, // _invokeBasic, _linkToVirtual
724 Symbol* signature, //anything at all
725 TRAPSJavaThread* __the_thread__);
726 static Klass* check_non_bcp_klass(Klass* klass);
727
728 enum {
729 // How many extra stack entries for invokedynamic
730 extra_stack_entries_for_jsr292 = 1
731 };
732
733 // this operates only on invoke methods:
734 // presize interpreter frames for extra interpreter stack entries, if needed
735 // Account for the extra appendix argument for invokehandle/invokedynamic
736 static int extra_stack_entries() { return extra_stack_entries_for_jsr292; }
737 static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize
738
739 // RedefineClasses() support:
740 bool is_old() const { return access_flags().is_old(); }
741 void set_is_old() { _access_flags.set_is_old(); }
742 bool is_obsolete() const { return access_flags().is_obsolete(); }
743 void set_is_obsolete() { _access_flags.set_is_obsolete(); }
744 bool is_deleted() const { return access_flags().is_deleted(); }
745 void set_is_deleted() { _access_flags.set_is_deleted(); }
746
747 bool on_stack() const { return access_flags().on_stack(); }
748 void set_on_stack(const bool value);
749
750 // see the definition in Method*.cpp for the gory details
751 bool should_not_be_cached() const;
752
753 // JVMTI Native method prefixing support:
754 bool is_prefixed_native() const { return access_flags().is_prefixed_native(); }
755 void set_is_prefixed_native() { _access_flags.set_is_prefixed_native(); }
756
757 // Rewriting support
758 static methodHandle clone_with_new_data(const methodHandle& m, u_char* new_code, int new_code_length,
759 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPSJavaThread* __the_thread__);
760
761 // jmethodID handling
762 // Because the useful life-span of a jmethodID cannot be determined,
763 // once created they are never reclaimed. The methods to which they refer,
764 // however, can be GC'ed away if the class is unloaded or if the method is
765 // made obsolete or deleted -- in these cases, the jmethodID
766 // refers to NULL (as is the case for any weak reference).
767 static jmethodID make_jmethod_id(ClassLoaderData* loader_data, Method* mh);
768 static void destroy_jmethod_id(ClassLoaderData* loader_data, jmethodID mid);
769
770 // Ensure there is enough capacity in the internal tracking data
771 // structures to hold the number of jmethodIDs you plan to generate.
772 // This saves substantial time doing allocations.
773 static void ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity);
774
775 // Use resolve_jmethod_id() in situations where the caller is expected
776 // to provide a valid jmethodID; the only sanity checks are in asserts;
777 // result guaranteed not to be NULL.
778 inline static Method* resolve_jmethod_id(jmethodID mid) {
779 assert(mid != NULL, "JNI method id should not be null")do { if (!(mid != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 779, "assert(" "mid != __null" ") failed", "JNI method id should not be null"
); ::breakpoint(); } } while (0)
;
780 return *((Method**)mid);
781 }
782
783 // Use checked_resolve_jmethod_id() in situations where the caller
784 // should provide a valid jmethodID, but might not. NULL is returned
785 // when the jmethodID does not refer to a valid method.
786 static Method* checked_resolve_jmethod_id(jmethodID mid);
787
788 static void change_method_associated_with_jmethod_id(jmethodID old_jmid_ptr, Method* new_method);
789 static bool is_method_id(jmethodID mid);
790
791 // Clear methods
792 static void clear_jmethod_ids(ClassLoaderData* loader_data);
793 static void print_jmethod_ids_count(const ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN;
794
795 // Get this method's jmethodID -- allocate if it doesn't exist
796 jmethodID jmethod_id();
797
798 // Lookup the jmethodID for this method. Return NULL if not found.
799 // NOTE that this function can be called from a signal handler
800 // (see AsyncGetCallTrace support for Forte Analyzer) and this
801 // needs to be async-safe. No allocation should be done and
802 // so handles are not used to avoid deadlock.
803 jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); }
804
805 // Support for inlining of intrinsic methods
806 vmIntrinsicID intrinsic_id() const { return (vmIntrinsicID) _intrinsic_id; }
807 void set_intrinsic_id(vmIntrinsicID id) { _intrinsic_id = (u2) id; }
808
809 // Helper routines for intrinsic_id() and vmIntrinsics::method().
810 void init_intrinsic_id(vmSymbolID klass_id); // updates from _none if a match
811 static vmSymbolID klass_id_for_intrinsics(const Klass* holder);
812
813 bool caller_sensitive() {
814 return (_flags & _caller_sensitive) != 0;
815 }
816 void set_caller_sensitive(bool x) {
817 _flags = x ? (_flags | _caller_sensitive) : (_flags & ~_caller_sensitive);
818 }
819
820 bool force_inline() {
821 return (_flags & _force_inline) != 0;
822 }
823 void set_force_inline(bool x) {
824 _flags = x ? (_flags | _force_inline) : (_flags & ~_force_inline);
825 }
826
827 bool dont_inline() {
828 return (_flags & _dont_inline) != 0;
829 }
830 void set_dont_inline(bool x) {
831 _flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline);
832 }
833
834 bool is_hidden() const {
835 return (_flags & _hidden) != 0;
836 }
837
838 void set_hidden(bool x) {
839 _flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
840 }
841
842 bool is_scoped() const {
843 return (_flags & _scoped) != 0;
844 }
845
846 void set_scoped(bool x) {
847 _flags = x ? (_flags | _scoped) : (_flags & ~_scoped);
848 }
849
850 bool intrinsic_candidate() {
851 return (_flags & _intrinsic_candidate) != 0;
852 }
853 void set_intrinsic_candidate(bool x) {
854 _flags = x ? (_flags | _intrinsic_candidate) : (_flags & ~_intrinsic_candidate);
855 }
856
857 bool has_injected_profile() {
858 return (_flags & _has_injected_profile) != 0;
859 }
860 void set_has_injected_profile(bool x) {
861 _flags = x ? (_flags | _has_injected_profile) : (_flags & ~_has_injected_profile);
862 }
863
864 bool has_reserved_stack_access() {
865 return (_flags & _reserved_stack_access) != 0;
866 }
867
868 void set_has_reserved_stack_access(bool x) {
869 _flags = x ? (_flags | _reserved_stack_access) : (_flags & ~_reserved_stack_access);
870 }
871
872 JFR_ONLY(DEFINE_TRACE_FLAG_ACCESSOR;)bool is_trace_flag_set(jshort flag) const { return _trace_flags
.is_set(flag); } jshort trace_flags() const { return _trace_flags
.flags(); } void set_trace_flags(jshort flags) const { _trace_flags
.set_flags(flags); } jbyte* trace_flags_addr() const { return
_trace_flags.flags_addr(); } jbyte* trace_meta_addr() const {
return _trace_flags.meta_addr(); };
873
874 ConstMethod::MethodType method_type() const {
875 return _constMethod->method_type();
876 }
877 bool is_overpass() const { return method_type() == ConstMethod::OVERPASS; }
878
879 // On-stack replacement support
880 bool has_osr_nmethod(int level, bool match_level) {
881 return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL__null;
882 }
883
884 int mark_osr_nmethods() {
885 return method_holder()->mark_osr_nmethods(this);
886 }
887
888 nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) {
889 return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
890 }
891
892 // Find if klass for method is loaded
893 bool is_klass_loaded_by_klass_index(int klass_index) const;
894 bool is_klass_loaded(int refinfo_index, bool must_be_resolved = false) const;
895
896 // Indicates whether compilation failed earlier for this method, or
897 // whether it is not compilable for another reason like having a
898 // breakpoint set in it.
899 bool is_not_compilable(int comp_level = CompLevel_any) const;
900 void set_not_compilable(const char* reason, int comp_level = CompLevel_all, bool report = true);
901 void set_not_compilable_quietly(const char* reason, int comp_level = CompLevel_all) {
902 set_not_compilable(reason, comp_level, false);
903 }
904 bool is_not_osr_compilable(int comp_level = CompLevel_any) const;
905 void set_not_osr_compilable(const char* reason, int comp_level = CompLevel_all, bool report = true);
906 void set_not_osr_compilable_quietly(const char* reason, int comp_level = CompLevel_all) {
907 set_not_osr_compilable(reason, comp_level, false);
908 }
909 bool is_always_compilable() const;
910
911 private:
912 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
913
914 public:
915 MethodCounters* get_method_counters(Thread* current) {
916 if (_method_counters == NULL__null) {
917 build_method_counters(current, this);
918 }
919 return _method_counters;
920 }
921
922 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
923 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
924 void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); }
925 bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); }
926 void set_not_c2_compilable() { _access_flags.set_not_c2_compilable(); }
927 void clear_not_c2_compilable() { _access_flags.clear_not_c2_compilable(); }
928
929 bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); } // don't waste an accessFlags bit
930 void set_not_c1_osr_compilable() { set_not_c1_compilable(); } // don't waste an accessFlags bit
931 void clear_not_c1_osr_compilable() { clear_not_c1_compilable(); } // don't waste an accessFlags bit
932 bool is_not_c2_osr_compilable() const { return access_flags().is_not_c2_osr_compilable(); }
933 void set_not_c2_osr_compilable() { _access_flags.set_not_c2_osr_compilable(); }
934 void clear_not_c2_osr_compilable() { _access_flags.clear_not_c2_osr_compilable(); }
935
936 // Background compilation support
937 bool queued_for_compilation() const { return access_flags().queued_for_compilation(); }
938 void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); }
939 void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); }
940
941 // Resolve all classes in signature, return 'true' if successful
942 static bool load_signature_classes(const methodHandle& m, TRAPSJavaThread* __the_thread__);
943
944 // Return if true if not all classes references in signature, including return type, has been loaded
945 static bool has_unloaded_classes_in_signature(const methodHandle& m, TRAPSJavaThread* __the_thread__);
946
947 // Printing
948 void print_short_name(outputStream* st = tty); // prints as klassname::methodname; Exposed so field engineers can debug VM
949#if INCLUDE_JVMTI1
950 void print_name(outputStream* st = tty); // prints as "virtual void foo(int)"; exposed for -Xlog:redefine+class
951#else
952 void print_name(outputStream* st = tty) PRODUCT_RETURN; // prints as "virtual void foo(int)"
953#endif
954
955 typedef int (*method_comparator_func)(Method* a, Method* b);
956
957 // Helper routine used for method sorting
958 static void sort_methods(Array<Method*>* methods, bool set_idnums = true, method_comparator_func func = NULL__null);
959
960 // Deallocation function for redefine classes or if an error occurs
961 void deallocate_contents(ClassLoaderData* loader_data);
962
963 void release_C_heap_structures();
964
965 Method* get_new_method() const {
966 InstanceKlass* holder = method_holder();
967 Method* new_method = holder->method_with_idnum(orig_method_idnum());
968
969 assert(new_method != NULL, "method_with_idnum() should not be NULL")do { if (!(new_method != __null)) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 969, "assert(" "new_method != __null" ") failed", "method_with_idnum() should not be NULL"
); ::breakpoint(); } } while (0)
;
970 assert(this != new_method, "sanity check")do { if (!(this != new_method)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 970, "assert(" "this != new_method" ") failed", "sanity check"
); ::breakpoint(); } } while (0)
;
971 return new_method;
972 }
973
974 // Printing
975#ifndef PRODUCT
976 void print_on(outputStream* st) const;
977#endif
978 void print_value_on(outputStream* st) const;
979 void print_linkage_flags(outputStream* st) PRODUCT_RETURN;
980
981 const char* internal_name() const { return "{method}"; }
982
983 // Check for valid method pointer
984 static bool has_method_vptr(const void* ptr);
985 static bool is_valid_method(const Method* m);
986
987 // Verify
988 void verify() { verify_on(tty); }
989 void verify_on(outputStream* st);
990
991 private:
992
993 // Inlined elements
994 address* native_function_addr() const { assert(is_native(), "must be native")do { if (!(is_native())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 994, "assert(" "is_native()" ") failed", "must be native");
::breakpoint(); } } while (0)
; return (address*) (this+1); }
995 address* signature_handler_addr() const { return native_function_addr() + 1; }
996};
997
998
999// Utility class for compressing line number tables
1000
1001class CompressedLineNumberWriteStream: public CompressedWriteStream {
1002 private:
1003 int _bci;
1004 int _line;
1005 public:
1006 // Constructor
1007 CompressedLineNumberWriteStream(int initial_size) : CompressedWriteStream(initial_size), _bci(0), _line(0) {}
1008 CompressedLineNumberWriteStream(u_char* buffer, int initial_size) : CompressedWriteStream(buffer, initial_size), _bci(0), _line(0) {}
1009
1010 // Write (bci, line number) pair to stream
1011 void write_pair_regular(int bci_delta, int line_delta);
1012
1013 // If (bci delta, line delta) fits in (5-bit unsigned, 3-bit unsigned)
1014 // we save it as one byte, otherwise we write a 0xFF escape character
1015 // and use regular compression. 0x0 is used as end-of-stream terminator.
1016 void write_pair_inline(int bci, int line);
1017
1018 void write_pair(int bci, int line);
1019
1020 // Write end-of-stream marker
1021 void write_terminator() { write_byte(0); }
1022};
1023
1024
1025// Utility class for decompressing line number tables
1026
1027class CompressedLineNumberReadStream: public CompressedReadStream {
1028 private:
1029 int _bci;
1030 int _line;
1031 public:
1032 // Constructor
1033 CompressedLineNumberReadStream(u_char* buffer);
1034 // Read (bci, line number) pair from stream. Returns false at end-of-stream.
1035 bool read_pair();
1036 // Accessing bci and line number (after calling read_pair)
1037 int bci() const { return _bci; }
1038 int line() const { return _line; }
1039};
1040
1041
1042#if INCLUDE_JVMTI1
1043
1044/// Fast Breakpoints.
1045
1046// If this structure gets more complicated (because bpts get numerous),
1047// move it into its own header.
1048
1049// There is presently no provision for concurrent access
1050// to breakpoint lists, which is only OK for JVMTI because
1051// breakpoints are written only at safepoints, and are read
1052// concurrently only outside of safepoints.
1053
1054class BreakpointInfo : public CHeapObj<mtClass> {
1055 friend class VMStructs;
1056 private:
1057 Bytecodes::Code _orig_bytecode;
1058 int _bci;
1059 u2 _name_index; // of method
1060 u2 _signature_index; // of method
1061 BreakpointInfo* _next; // simple storage allocation
1062
1063 public:
1064 BreakpointInfo(Method* m, int bci);
1065
1066 // accessors
1067 Bytecodes::Code orig_bytecode() { return _orig_bytecode; }
1068 void set_orig_bytecode(Bytecodes::Code code) { _orig_bytecode = code; }
1069 int bci() { return _bci; }
1070
1071 BreakpointInfo* next() const { return _next; }
1072 void set_next(BreakpointInfo* n) { _next = n; }
1073
1074 // helps for searchers
1075 bool match(const Method* m, int bci) {
1076 return bci == _bci && match(m);
1077 }
1078
1079 bool match(const Method* m) {
1080 return _name_index == m->name_index() &&
1081 _signature_index == m->signature_index();
1082 }
1083
1084 void set(Method* method);
1085 void clear(Method* method);
1086};
1087
1088#endif // INCLUDE_JVMTI
1089
1090// Utility class for access exception handlers
1091class ExceptionTable : public StackObj {
1092 private:
1093 ExceptionTableElement* _table;
1094 u2 _length;
1095
1096 public:
1097 ExceptionTable(const Method* m) {
1098 if (m->has_exception_handler()) {
1099 _table = m->exception_table_start();
1100 _length = m->exception_table_length();
1101 } else {
1102 _table = NULL__null;
1103 _length = 0;
1104 }
1105 }
1106
1107 int length() const {
1108 return _length;
1109 }
1110
1111 u2 start_pc(int idx) const {
1112 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1112, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1113 return _table[idx].start_pc;
1114 }
1115
1116 void set_start_pc(int idx, u2 value) {
1117 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1117, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1118 _table[idx].start_pc = value;
1119 }
1120
1121 u2 end_pc(int idx) const {
1122 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1122, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1123 return _table[idx].end_pc;
1124 }
1125
1126 void set_end_pc(int idx, u2 value) {
1127 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1127, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1128 _table[idx].end_pc = value;
1129 }
1130
1131 u2 handler_pc(int idx) const {
1132 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1132, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1133 return _table[idx].handler_pc;
1134 }
1135
1136 void set_handler_pc(int idx, u2 value) {
1137 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1137, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1138 _table[idx].handler_pc = value;
1139 }
1140
1141 u2 catch_type_index(int idx) const {
1142 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1142, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1143 return _table[idx].catch_type_index;
1144 }
1145
1146 void set_catch_type_index(int idx, u2 value) {
1147 assert(idx < _length, "out of bounds")do { if (!(idx < _length)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/method.hpp"
, 1147, "assert(" "idx < _length" ") failed", "out of bounds"
); ::breakpoint(); } } while (0)
;
1148 _table[idx].catch_type_index = value;
1149 }
1150};
1151
1152#endif // SHARE_OOPS_METHOD_HPP

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

1/*
2 * Copyright (c) 2003, 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_OOPS_CONSTMETHOD_HPP
26#define SHARE_OOPS_CONSTMETHOD_HPP
27
28#include "oops/oop.hpp"
29#include "utilities/align.hpp"
30
31// An ConstMethod represents portions of a Java method which are not written to after
32// the classfile is parsed(*see below). This part of the method can be shared across
33// processes in a read-only section with Class Data Sharing (CDS). It's important
34// that this class doesn't have virtual functions because the vptr cannot be shared
35// with CDS.
36//
37// Note that most applications load thousands of methods, so keeping the size of this
38// structure small has a big impact on footprint.
39
40// The actual bytecodes are inlined after the end of the ConstMethod struct.
41//
42// The line number table is compressed and inlined following the byte codes. It is
43// found as the first byte following the byte codes. Note that accessing the line
44// number and local variable tables is not performance critical at all.
45//
46// The checked exceptions table and the local variable table are inlined after the
47// line number table, and indexed from the end of the method. We do not compress the
48// checked exceptions table since the average length is less than 2, and it is used
49// by reflection so access should be fast. We do not bother to compress the local
50// variable table either since it is mostly absent.
51//
52//
53// ConstMethod embedded field layout (after declared fields):
54// [EMBEDDED byte codes]
55// [EMBEDDED compressed linenumber table]
56// (see class CompressedLineNumberReadStream)
57// (note that length is unknown until decompressed)
58// (access flags bit tells whether table is present)
59// (indexed from start of ConstMethod)
60// (elements not necessarily sorted!)
61// [EMBEDDED localvariable table elements + length (length last)]
62// (length is u2, elements are 6-tuples of u2)
63// (see class LocalVariableTableElement)
64// (access flags bit tells whether table is present)
65// (indexed from end of ConstMethod*)
66// [EMBEDDED exception table + length (length last)]
67// (length is u2, elements are 4-tuples of u2)
68// (see class ExceptionTableElement)
69// (access flags bit tells whether table is present)
70// (indexed from end of ConstMethod*)
71// [EMBEDDED checked exceptions elements + length (length last)]
72// (length is u2, elements are u2)
73// (see class CheckedExceptionElement)
74// (access flags bit tells whether table is present)
75// (indexed from end of ConstMethod*)
76// [EMBEDDED method parameters elements + length (length last)]
77// (length is u2, elements are u2, u4 structures)
78// (see class MethodParametersElement)
79// (access flags bit tells whether table is present)
80// (indexed from end of ConstMethod*)
81// [EMBEDDED generic signature index (u2)]
82// (indexed from end of constMethodOop)
83// [EMBEDDED annotations arrays - method, parameter, type, default]
84// pointer to Array<u1> if annotation is present
85//
86// IMPORTANT: If anything gets added here, there need to be changes to
87// ensure that ServicabilityAgent doesn't get broken as a result!
88
89
90// Utility class describing elements in checked exceptions table inlined in Method*.
91class CheckedExceptionElement {
92 public:
93 u2 class_cp_index;
94};
95
96
97// Utility class describing elements in local variable table inlined in Method*.
98class LocalVariableTableElement {
99 public:
100 u2 start_bci;
101 u2 length;
102 u2 name_cp_index;
103 u2 descriptor_cp_index;
104 u2 signature_cp_index;
105 u2 slot;
106};
107
108// Utility class describing elements in exception table
109class ExceptionTableElement {
110 public:
111 u2 start_pc;
112 u2 end_pc;
113 u2 handler_pc;
114 u2 catch_type_index;
115};
116
117// Utility class describing elements in method parameters
118class MethodParametersElement {
119 public:
120 u2 name_cp_index;
121 u2 flags;
122};
123
124// Class to collect the sizes of ConstMethod inline tables
125#define INLINE_TABLES_DO(do_element)do_element(localvariable_table_length) do_element(compressed_linenumber_size
) do_element(exception_table_length) do_element(checked_exceptions_length
) do_element(method_parameters_length) do_element(generic_signature_index
) do_element(method_annotations_length) do_element(parameter_annotations_length
) do_element(type_annotations_length) do_element(default_annotations_length
)
\
126 do_element(localvariable_table_length) \
127 do_element(compressed_linenumber_size) \
128 do_element(exception_table_length) \
129 do_element(checked_exceptions_length) \
130 do_element(method_parameters_length) \
131 do_element(generic_signature_index) \
132 do_element(method_annotations_length) \
133 do_element(parameter_annotations_length) \
134 do_element(type_annotations_length) \
135 do_element(default_annotations_length)
136
137#define INLINE_TABLE_DECLARE(sym) int _##sym;
138#define INLINE_TABLE_PARAM(sym) int sym,
139#define INLINE_TABLE_INIT(sym) _##sym(sym),
140#define INLINE_TABLE_NULL(sym) _##sym(0),
141#define INLINE_TABLE_ACCESSOR(sym) int sym() const { return _##sym; }
142
143class InlineTableSizes : StackObj {
144 // declarations
145 INLINE_TABLES_DO(INLINE_TABLE_DECLARE)INLINE_TABLE_DECLARE(localvariable_table_length) INLINE_TABLE_DECLARE
(compressed_linenumber_size) INLINE_TABLE_DECLARE(exception_table_length
) INLINE_TABLE_DECLARE(checked_exceptions_length) INLINE_TABLE_DECLARE
(method_parameters_length) INLINE_TABLE_DECLARE(generic_signature_index
) INLINE_TABLE_DECLARE(method_annotations_length) INLINE_TABLE_DECLARE
(parameter_annotations_length) INLINE_TABLE_DECLARE(type_annotations_length
) INLINE_TABLE_DECLARE(default_annotations_length)
146 int _end;
147 public:
148 InlineTableSizes(
149 INLINE_TABLES_DO(INLINE_TABLE_PARAM)INLINE_TABLE_PARAM(localvariable_table_length) INLINE_TABLE_PARAM
(compressed_linenumber_size) INLINE_TABLE_PARAM(exception_table_length
) INLINE_TABLE_PARAM(checked_exceptions_length) INLINE_TABLE_PARAM
(method_parameters_length) INLINE_TABLE_PARAM(generic_signature_index
) INLINE_TABLE_PARAM(method_annotations_length) INLINE_TABLE_PARAM
(parameter_annotations_length) INLINE_TABLE_PARAM(type_annotations_length
) INLINE_TABLE_PARAM(default_annotations_length)
150 int end) :
151 INLINE_TABLES_DO(INLINE_TABLE_INIT)INLINE_TABLE_INIT(localvariable_table_length) INLINE_TABLE_INIT
(compressed_linenumber_size) INLINE_TABLE_INIT(exception_table_length
) INLINE_TABLE_INIT(checked_exceptions_length) INLINE_TABLE_INIT
(method_parameters_length) INLINE_TABLE_INIT(generic_signature_index
) INLINE_TABLE_INIT(method_annotations_length) INLINE_TABLE_INIT
(parameter_annotations_length) INLINE_TABLE_INIT(type_annotations_length
) INLINE_TABLE_INIT(default_annotations_length)
152 _end(end) {}
153
154 // Default constructor for no inlined tables
155 InlineTableSizes() :
156 INLINE_TABLES_DO(INLINE_TABLE_NULL)INLINE_TABLE_NULL(localvariable_table_length) INLINE_TABLE_NULL
(compressed_linenumber_size) INLINE_TABLE_NULL(exception_table_length
) INLINE_TABLE_NULL(checked_exceptions_length) INLINE_TABLE_NULL
(method_parameters_length) INLINE_TABLE_NULL(generic_signature_index
) INLINE_TABLE_NULL(method_annotations_length) INLINE_TABLE_NULL
(parameter_annotations_length) INLINE_TABLE_NULL(type_annotations_length
) INLINE_TABLE_NULL(default_annotations_length)
157 _end(0) {}
158
159 // Accessors
160 INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR)INLINE_TABLE_ACCESSOR(localvariable_table_length) INLINE_TABLE_ACCESSOR
(compressed_linenumber_size) INLINE_TABLE_ACCESSOR(exception_table_length
) INLINE_TABLE_ACCESSOR(checked_exceptions_length) INLINE_TABLE_ACCESSOR
(method_parameters_length) INLINE_TABLE_ACCESSOR(generic_signature_index
) INLINE_TABLE_ACCESSOR(method_annotations_length) INLINE_TABLE_ACCESSOR
(parameter_annotations_length) INLINE_TABLE_ACCESSOR(type_annotations_length
) INLINE_TABLE_ACCESSOR(default_annotations_length)
161};
162#undef INLINE_TABLE_ACCESSOR
163#undef INLINE_TABLE_NULL
164#undef INLINE_TABLE_INIT
165#undef INLINE_TABLE_PARAM
166#undef INLINE_TABLE_DECLARE
167
168class ConstMethod : public MetaspaceObj {
169 friend class VMStructs;
170 friend class JVMCIVMStructs;
171
172public:
173 typedef enum { NORMAL, OVERPASS } MethodType;
174
175private:
176 enum {
177 _has_linenumber_table = 0x0001,
178 _has_checked_exceptions = 0x0002,
179 _has_localvariable_table = 0x0004,
180 _has_exception_table = 0x0008,
181 _has_generic_signature = 0x0010,
182 _has_method_parameters = 0x0020,
183 _is_overpass = 0x0040,
184 _has_method_annotations = 0x0080,
185 _has_parameter_annotations = 0x0100,
186 _has_type_annotations = 0x0200,
187 _has_default_annotations = 0x0400
188 };
189
190 // Bit vector of signature
191 // Callers interpret 0=not initialized yet and
192 // -1=too many args to fix, must parse the slow way.
193 // The real initial value is special to account for nonatomicity of 64 bit
194 // loads and stores. This value may updated and read without a lock by
195 // multiple threads, so is volatile.
196 volatile uint64_t _fingerprint;
197
198 // If you add a new field that points to any metaspace object, you
199 // must add this field to ConstMethod::metaspace_pointers_do().
200
201 ConstantPool* _constants; // Constant pool
202
203 // Raw stackmap data for the method
204 Array<u1>* _stackmap_data;
205
206 int _constMethod_size;
207 u2 _flags;
208 u1 _result_type; // BasicType of result
209
210 // Size of Java bytecodes allocated immediately after Method*.
211 u2 _code_size;
212 u2 _name_index; // Method name (index in constant pool)
213 u2 _signature_index; // Method signature (index in constant pool)
214 u2 _method_idnum; // unique identification number for the method within the class
215 // initially corresponds to the index into the methods array.
216 // but this may change with redefinition
217 u2 _max_stack; // Maximum number of entries on the expression stack
218 u2 _max_locals; // Number of local variables used by this method
219 u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words
220 u2 _orig_method_idnum; // Original unique identification number for the method
221
222 // Constructor
223 ConstMethod(int byte_code_size,
224 InlineTableSizes* sizes,
225 MethodType is_overpass,
226 int size);
227public:
228
229 static ConstMethod* allocate(ClassLoaderData* loader_data,
230 int byte_code_size,
231 InlineTableSizes* sizes,
232 MethodType mt,
233 TRAPSJavaThread* __the_thread__);
234
235 // Inlined tables
236 void set_inlined_tables_length(InlineTableSizes* sizes);
237
238 bool has_generic_signature() const
239 { return (_flags & _has_generic_signature) != 0; }
240
241 bool has_linenumber_table() const
242 { return (_flags & _has_linenumber_table) != 0; }
243
244 bool has_checked_exceptions() const
245 { return (_flags & _has_checked_exceptions) != 0; }
246
247 bool has_localvariable_table() const
248 { return (_flags & _has_localvariable_table) != 0; }
249
250 bool has_exception_handler() const
251 { return (_flags & _has_exception_table) != 0; }
252
253 bool has_method_parameters() const
254 { return (_flags & _has_method_parameters) != 0; }
255
256 MethodType method_type() const {
257 return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;
258 }
259
260 void set_method_type(MethodType mt) {
261 if (mt == NORMAL) {
262 _flags &= ~(_is_overpass);
263 } else {
264 _flags |= _is_overpass;
265 }
266 }
267
268 // constant pool
269 ConstantPool* constants() const { return _constants; }
270 void set_constants(ConstantPool* c) { _constants = c; }
271
272 Method* method() const;
273
274 // stackmap table data
275 Array<u1>* stackmap_data() const { return _stackmap_data; }
276 void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
277 void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPSJavaThread* __the_thread__);
278 bool has_stackmap_table() const { return _stackmap_data != NULL__null; }
279
280 void init_fingerprint() {
281 const uint64_t initval = UCONST64(0x8000000000000000)(0x8000000000000000ULL);
282 _fingerprint = initval;
283 }
284
285 uint64_t fingerprint() const {
286 // Since reads aren't atomic for 64 bits, if any of the high or low order
287 // word is the initial value, return 0. See init_fingerprint for initval.
288 uint high_fp = (uint)(_fingerprint >> 32);
289 if ((int) _fingerprint == 0 || high_fp == 0x80000000) {
290 return 0L;
291 } else {
292 return _fingerprint;
293 }
294 }
295
296 uint64_t set_fingerprint(uint64_t new_fingerprint) {
297#ifdef ASSERT1
298 // Assert only valid if complete/valid 64 bit _fingerprint value is read.
299 uint64_t oldfp = fingerprint();
300#endif // ASSERT
301 _fingerprint = new_fingerprint;
302 assert(oldfp == 0L || new_fingerprint == oldfp,do { if (!(oldfp == 0L || new_fingerprint == oldfp)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 303, "assert(" "oldfp == 0L || new_fingerprint == oldfp" ") failed"
, "fingerprint cannot change"); ::breakpoint(); } } while (0)
303 "fingerprint cannot change")do { if (!(oldfp == 0L || new_fingerprint == oldfp)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 303, "assert(" "oldfp == 0L || new_fingerprint == oldfp" ") failed"
, "fingerprint cannot change"); ::breakpoint(); } } while (0)
;
304 assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0,do { if (!(((new_fingerprint >> 32) != 0x80000000) &&
(int)new_fingerprint !=0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 305, "assert(" "((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0"
") failed", "fingerprint should call init to set initial value"
); ::breakpoint(); } } while (0)
305 "fingerprint should call init to set initial value")do { if (!(((new_fingerprint >> 32) != 0x80000000) &&
(int)new_fingerprint !=0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 305, "assert(" "((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0"
") failed", "fingerprint should call init to set initial value"
); ::breakpoint(); } } while (0)
;
306 return new_fingerprint;
307 }
308
309 // name
310 int name_index() const { return _name_index; }
311 void set_name_index(int index) { _name_index = index; }
312
313 // signature
314 int signature_index() const { return _signature_index; }
315 void set_signature_index(int index) { _signature_index = index; }
316
317 // generics support
318 int generic_signature_index() const {
319 if (has_generic_signature()) {
320 return *generic_signature_index_addr();
321 } else {
322 return 0;
323 }
324 }
325 void set_generic_signature_index(u2 index) {
326 assert(has_generic_signature(), "")do { if (!(has_generic_signature())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 326, "assert(" "has_generic_signature()" ") failed", ""); ::
breakpoint(); } } while (0)
;
327 u2* addr = generic_signature_index_addr();
328 *addr = index;
329 }
330
331 // Sizing
332 static int header_size() {
333 return align_up((int)sizeof(ConstMethod), wordSize) / wordSize;
334 }
335
336 // Size needed
337 static int size(int code_size, InlineTableSizes* sizes);
338
339 int size() const { return _constMethod_size;}
340 void set_constMethod_size(int size) { _constMethod_size = size; }
341
342 // ConstMethods should be stored in the read-only region of CDS archive.
343 static bool is_read_only_by_default() { return true; }
344
345 // code size
346 int code_size() const { return _code_size; }
347 void set_code_size(int size) {
348 assert(max_method_code_size < (1 << 16),do { if (!(max_method_code_size < (1 << 16))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 349, "assert(" "max_method_code_size < (1 << 16)" ") failed"
, "u2 is too small to hold method code size in general"); ::breakpoint
(); } } while (0)
349 "u2 is too small to hold method code size in general")do { if (!(max_method_code_size < (1 << 16))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 349, "assert(" "max_method_code_size < (1 << 16)" ") failed"
, "u2 is too small to hold method code size in general"); ::breakpoint
(); } } while (0)
;
350 assert(0 <= size && size <= max_method_code_size, "invalid code size")do { if (!(0 <= size && size <= max_method_code_size
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 350, "assert(" "0 <= size && size <= max_method_code_size"
") failed", "invalid code size"); ::breakpoint(); } } while (
0)
;
351 _code_size = size;
352 }
353
354 // linenumber table - note that length is unknown until decompression,
355 // see class CompressedLineNumberReadStream.
356 u_char* compressed_linenumber_table() const; // not preserved by gc
357 u2* generic_signature_index_addr() const;
358 u2* checked_exceptions_length_addr() const;
359 u2* localvariable_table_length_addr() const;
360 u2* exception_table_length_addr() const;
361 u2* method_parameters_length_addr() const;
362
363 // checked exceptions
364 int checked_exceptions_length() const;
365 CheckedExceptionElement* checked_exceptions_start() const;
366
367 // localvariable table
368 int localvariable_table_length() const;
369 LocalVariableTableElement* localvariable_table_start() const;
370
371 // exception table
372 int exception_table_length() const;
373 ExceptionTableElement* exception_table_start() const;
374
375 // method parameters table
376
377 // This returns -1 if no parameters are present, a non-negative
378 // value otherwise. Note: sometimes, there are 0-length parameters
379 // attributes that must be reported up to the reflection API all the
380 // same.
381 int method_parameters_length() const;
382 MethodParametersElement* method_parameters_start() const;
383
384 // method annotations
385 bool has_method_annotations() const
386 { return (_flags & _has_method_annotations) != 0; }
387
388 bool has_parameter_annotations() const
389 { return (_flags & _has_parameter_annotations) != 0; }
390
391 bool has_type_annotations() const
392 { return (_flags & _has_type_annotations) != 0; }
393
394 bool has_default_annotations() const
395 { return (_flags & _has_default_annotations) != 0; }
396
397
398 AnnotationArray** method_annotations_addr() const;
399 AnnotationArray* method_annotations() const {
400 return has_method_annotations() ? *(method_annotations_addr()) : NULL__null;
401 }
402 void set_method_annotations(AnnotationArray* anno) {
403 *(method_annotations_addr()) = anno;
404 }
405
406 AnnotationArray** parameter_annotations_addr() const;
407 AnnotationArray* parameter_annotations() const {
408 return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL__null;
409 }
410 void set_parameter_annotations(AnnotationArray* anno) {
411 *(parameter_annotations_addr()) = anno;
412 }
413
414 AnnotationArray** type_annotations_addr() const;
415 AnnotationArray* type_annotations() const {
416 return has_type_annotations() ? *(type_annotations_addr()) : NULL__null;
417 }
418 void set_type_annotations(AnnotationArray* anno) {
419 *(type_annotations_addr()) = anno;
420 }
421
422 AnnotationArray** default_annotations_addr() const;
423 AnnotationArray* default_annotations() const {
424 return has_default_annotations() ? *(default_annotations_addr()) : NULL__null;
425 }
426 void set_default_annotations(AnnotationArray* anno) {
427 *(default_annotations_addr()) = anno;
428 }
429
430 int method_annotations_length() const {
431 return has_method_annotations() ? method_annotations()->length() : 0;
432 }
433 int parameter_annotations_length() const {
434 return has_parameter_annotations() ? parameter_annotations()->length() : 0;
435 }
436 int type_annotations_length() const {
437 return has_type_annotations() ? type_annotations()->length() : 0;
438 }
439 int default_annotations_length() const {
440 return has_default_annotations() ? default_annotations()->length() : 0;
441 }
442
443 // Copy annotations from other ConstMethod
444 void copy_annotations_from(ClassLoaderData* loader_data, ConstMethod* cm, TRAPSJavaThread* __the_thread__);
445
446 // byte codes
447 void set_code(address code) {
448 if (code_size() > 0) {
42
Assuming the condition is true
43
Taking true branch
449 memcpy(code_base(), code, code_size());
44
Null pointer passed to 2nd parameter expecting 'nonnull'
450 }
451 }
452 address code_base() const { return (address) (this+1); }
453 address code_end() const { return code_base() + code_size(); }
454 bool contains(address bcp) const { return code_base() <= bcp
455 && bcp < code_end(); }
456 // Offset to bytecodes
457 static ByteSize codes_offset()
458 { return in_ByteSize(sizeof(ConstMethod)); }
459
460 static ByteSize constants_offset()
461 { return byte_offset_of(ConstMethod, _constants)in_ByteSize((int)(size_t)((intx)&(((ConstMethod*)16)->
_constants) - 16))
; }
462
463 static ByteSize max_stack_offset()
464 { return byte_offset_of(ConstMethod, _max_stack)in_ByteSize((int)(size_t)((intx)&(((ConstMethod*)16)->
_max_stack) - 16))
; }
465 static ByteSize size_of_locals_offset()
466 { return byte_offset_of(ConstMethod, _max_locals)in_ByteSize((int)(size_t)((intx)&(((ConstMethod*)16)->
_max_locals) - 16))
; }
467 static ByteSize size_of_parameters_offset()
468 { return byte_offset_of(ConstMethod, _size_of_parameters)in_ByteSize((int)(size_t)((intx)&(((ConstMethod*)16)->
_size_of_parameters) - 16))
; }
469
470 static ByteSize result_type_offset()
471 { return byte_offset_of(ConstMethod, _result_type)in_ByteSize((int)(size_t)((intx)&(((ConstMethod*)16)->
_result_type) - 16))
; }
472
473 // Unique id for the method
474 static const u2 MAX_IDNUM;
475 static const u2 UNSET_IDNUM;
476 u2 method_idnum() const { return _method_idnum; }
477 void set_method_idnum(u2 idnum) { _method_idnum = idnum; }
478
479 u2 orig_method_idnum() const { return _orig_method_idnum; }
480 void set_orig_method_idnum(u2 idnum) { _orig_method_idnum = idnum; }
481
482 // max stack
483 int max_stack() const { return _max_stack; }
484 void set_max_stack(int size) { _max_stack = size; }
485
486 // max locals
487 int max_locals() const { return _max_locals; }
488 void set_max_locals(int size) { _max_locals = size; }
489
490 // size of parameters
491 int size_of_parameters() const { return _size_of_parameters; }
492 void set_size_of_parameters(int size) { _size_of_parameters = size; }
493
494 // result type (basic type of return value)
495 BasicType result_type() const { assert(_result_type >= T_BOOLEAN, "Must be set")do { if (!(_result_type >= T_BOOLEAN)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 495, "assert(" "_result_type >= T_BOOLEAN" ") failed", "Must be set"
); ::breakpoint(); } } while (0)
;
496 return (BasicType)_result_type; }
497
498 void set_result_type(BasicType rt) { assert(rt < 16, "result type too large")do { if (!(rt < 16)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/constMethod.hpp"
, 498, "assert(" "rt < 16" ") failed", "result type too large"
); ::breakpoint(); } } while (0)
;
499 _result_type = (u1)rt; }
500 // Deallocation for RedefineClasses
501 void deallocate_contents(ClassLoaderData* loader_data);
502 bool is_klass() const { return false; }
503 DEBUG_ONLY(bool on_stack() { return false; })bool on_stack() { return false; }
504
505 void metaspace_pointers_do(MetaspaceClosure* it);
506 MetaspaceObj::Type type() const { return ConstMethodType; }
507private:
508 // Since the size of the compressed line number table is unknown, the
509 // offsets of the other variable sized sections are computed backwards
510 // from the end of the ConstMethod*.
511
512 // First byte after ConstMethod*
513 address constMethod_end() const
514 { return (address)((intptr_t*)this + _constMethod_size); }
515
516 // Last short in ConstMethod*
517 u2* last_u2_element() const;
518
519 public:
520 // Printing
521 void print_on (outputStream* st) const;
522 void print_value_on(outputStream* st) const;
523
524 const char* internal_name() const { return "{constMethod}"; }
525
526 // Verify
527 void verify_on(outputStream* st);
528};
529
530#endif // SHARE_OOPS_CONSTMETHOD_HPP