1 /*
2 * Copyright (c) 1998, 2025, 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_CODE_CODEBLOB_HPP
26 #define SHARE_CODE_CODEBLOB_HPP
27
28 #include "asm/codeBuffer.hpp"
29 #include "compiler/compilerDefinitions.hpp"
30 #include "compiler/oopMap.hpp"
31 #include "runtime/frame.hpp"
32 #include "runtime/handles.hpp"
33 #include "runtime/javaFrameAnchor.hpp"
34 #include "utilities/align.hpp"
35 #include "utilities/macros.hpp"
36
37 class ImmutableOopMap;
38 class ImmutableOopMapSet;
39 class JNIHandleBlock;
40 class OopMapSet;
41
42 // CodeBlob Types
43 // Used in the CodeCache to assign CodeBlobs to different CodeHeaps
44 enum class CodeBlobType {
45 MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods)
46 MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods
47 NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
48 All = 3, // All types (No code cache segmentation)
49 NumTypes = 4 // Number of CodeBlobTypes
50 };
51
52 // CodeBlob - superclass for all entries in the CodeCache.
53 //
54 // Subtypes are:
55 // nmethod : JIT Compiled Java methods
56 // RuntimeBlob : Non-compiled method code; generated glue code
57 // BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc.
58 // AdapterBlob : Used to hold C2I/I2C adapters
59 // VtableBlob : Used for holding vtable chunks
60 // MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
61 // RuntimeStub : Call to VM runtime methods
62 // SingletonBlob : Super-class for all blobs that exist in only one instance
63 // DeoptimizationBlob : Used for deoptimization
64 // SafepointBlob : Used to handle illegal instruction exceptions
65 // ExceptionBlob : Used for stack unrolling
66 // UncommonTrapBlob : Used to handle uncommon traps
67 // UpcallStub : Used for upcalls from native code
68 //
69 //
70 // Layout in the CodeCache:
71 // - header
72 // - content space
73 // - instruction space
74 // Outside of the CodeCache:
75 // - mutable_data
76 // - relocation info
77 // - additional data for subclasses
78
79 enum class CodeBlobKind : u1 {
80 None,
81 Nmethod,
82 Buffer,
83 Adapter,
84 Vtable,
85 MHAdapter,
86 RuntimeStub,
87 Deoptimization,
88 Safepoint,
89 #ifdef COMPILER2
90 Exception,
91 UncommonTrap,
92 #endif
93 Upcall,
94 Number_Of_Kinds
95 };
96
97 class UpcallStub; // for as_upcall_stub()
98 class RuntimeStub; // for as_runtime_stub()
99 class JavaFrameAnchor; // for UpcallStub::jfa_for_frame
100 class AdapterBlob;
101 class ExceptionBlob;
102 class DeoptimizationBlob;
103 class SafepointBlob;
104 class UncommonTrapBlob;
105
106 class CodeBlob {
107 friend class VMStructs;
108 friend class JVMCIVMStructs;
109
110 private:
111 void restore_mutable_data(address reloc_data);
112
113 protected:
114 // order fields from large to small to minimize padding between fields
115 ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob
116 const char* _name;
117 address _mutable_data;
118
119 int _size; // total size of CodeBlob in bytes
120 int _relocation_size; // size of relocation (could be bigger than 64Kb)
121 int _content_offset; // offset to where content region begins (this includes consts, insts, stubs)
122 int _code_offset; // offset to where instructions region begins (this includes insts, stubs)
123 int _data_offset; // offset to where data region begins
124 int _frame_size; // size of stack frame in words (NOT slots. On x64 these are 64bit words)
125 int _mutable_data_size;
126
127 S390_ONLY(int _ctable_offset;)
128
129 uint16_t _header_size; // size of header (depends on subclass)
130 int16_t _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have
131 // not finished setting up their frame. Beware of pc's in
132 // that range. There is a similar range(s) on returns
133 // which we don't detect.
134
135 CodeBlobKind _kind; // Kind of this code blob
136
137 bool _caller_must_gc_arguments;
138
139 #ifndef PRODUCT
140 AsmRemarks _asm_remarks;
141 DbgStrings _dbg_strings;
142 #endif
143
144 void print_on_impl(outputStream* st) const;
145 void print_value_on_impl(outputStream* st) const;
146
147 class Vptr {
148 public:
149 virtual void print_on(const CodeBlob* instance, outputStream* st) const = 0;
150 virtual void print_value_on(const CodeBlob* instance, outputStream* st) const = 0;
151 virtual void prepare_for_archiving(CodeBlob* instance) const {
152 instance->prepare_for_archiving_impl();
153 };
154 virtual void post_restore(CodeBlob* instance) const {
155 instance->post_restore_impl();
156 };
157 };
158
159 static const Vptr* vptr(CodeBlobKind kind);
160 const Vptr* vptr() const;
161
162 CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size,
163 int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments,
164 int mutable_data_size);
165
166 // Simple CodeBlob used for simple BufferBlob.
167 CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size);
168
169
170 void operator delete(void* p) { }
171
172 void prepare_for_archiving_impl();
173 void post_restore_impl();
174
175 public:
176
177 ~CodeBlob() NOT_DEBUG_RETURN;
178
179 // Returns the space needed for CodeBlob
180 static unsigned int allocation_size(CodeBuffer* cb, int header_size);
181 static unsigned int align_code_offset(int offset);
182
183 // Deletion
184 void purge();
185
186 // Typing
187 bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; }
188 bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; }
189 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
190 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
191 #ifdef COMPILER2
192 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
193 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
194 #else
195 bool is_uncommon_trap_stub() const { return false; }
196 bool is_exception_stub() const { return false; }
197 #endif
198 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
199 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
200 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
201 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
202 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
203
204 // Casting
205 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
206 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
207 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
208 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
209 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
210 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
211 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
212 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
213 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
214 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
215
216 // Boundaries
217 address header_begin() const { return (address) this; }
218 address header_end() const { return ((address) this) + _header_size; }
219 address content_begin() const { return (address) header_begin() + _content_offset; }
220 address content_end() const { return (address) header_begin() + _data_offset; }
221 address code_begin() const { return (address) header_begin() + _code_offset; }
222 address code_end() const { return (address) header_begin() + _data_offset; }
223 address data_begin() const { return (address) header_begin() + _data_offset; }
224 address data_end() const { return (address) header_begin() + _size; }
225 address blob_end() const { return (address) header_begin() + _size; }
226 // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor
227
228 int mutable_data_size() const { return _mutable_data_size; }
229 address mutable_data_begin() const { return _mutable_data; }
230 address mutable_data_end() const { return _mutable_data + _mutable_data_size; }
231
232 relocInfo* relocation_begin() const { return (relocInfo*)_mutable_data; }
233 relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); }
234
235 // Offsets
236 int content_offset() const { return _content_offset; }
237 int code_offset() const { return _code_offset; }
238
239 // This field holds the beginning of the const section in the old code buffer.
240 // It is needed to fix relocations of pc-relative loads when resizing the
241 // the constant pool or moving it.
242 S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; })
243 void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) }
244
245 // Sizes
246 int size() const { return _size; }
247 int header_size() const { return _header_size; }
248 int relocation_size() const { return _relocation_size; }
249 int content_size() const { return pointer_delta_as_int(content_end(), content_begin()); }
250 int code_size() const { return pointer_delta_as_int(code_end(), code_begin()); }
251
252 // Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed
253 void adjust_size(size_t used) {
254 _size = (int)used;
255 _data_offset = _size;
256 }
257
258 // Containment
259 bool blob_contains(address addr) const { return header_begin() <= addr && addr < blob_end(); }
260 bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }
261 bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); }
262 bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe &&
263 code_contains(addr) && addr >= code_begin() + _frame_complete_offset; }
264 int frame_complete_offset() const { return _frame_complete_offset; }
265
266 // OopMap for frame
267 ImmutableOopMapSet* oop_maps() const { return _oop_maps; }
268 void set_oop_maps(OopMapSet* p);
269 void set_oop_maps(ImmutableOopMapSet* p) { _oop_maps = p; }
270
271 const ImmutableOopMap* oop_map_for_slot(int slot, address return_address) const;
272 const ImmutableOopMap* oop_map_for_return_address(address return_address) const;
273
274 // Frame support. Sizes are in word units.
275 int frame_size() const { return _frame_size; }
276 void set_frame_size(int size) { _frame_size = size; }
277
278 // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
279 bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
280
281 // Naming
282 const char* name() const { return _name; }
283 void set_name(const char* name) { _name = name; }
284
285 // Debugging
286 void verify();
287 void print() const;
288 void print_on(outputStream* st) const;
289 void print_value_on(outputStream* st) const;
290
291 void dump_for_addr(address addr, outputStream* st, bool verbose) const;
292 void print_code_on(outputStream* st);
293
294 // Print to stream, any comments associated with offset.
295 void print_block_comment(outputStream* stream, address block_begin) const;
296
297 #ifndef PRODUCT
298 AsmRemarks &asm_remarks() { return _asm_remarks; }
299 DbgStrings &dbg_strings() { return _dbg_strings; }
300
301 void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); }
302 void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); }
303 #endif
304
305 void copy_to(address buffer) {
306 memcpy(buffer, this, this->size());
307 }
308
309 // methods to archive a blob into AOT code cache
310 void prepare_for_archiving();
311 static void archive_blob(CodeBlob* blob, address archive_buffer);
312
313 // methods to restore a blob from AOT code cache into the CodeCache
314 void post_restore();
315 CodeBlob* restore(address code_cache_buffer, const char* name, address archived_reloc_data, ImmutableOopMapSet* archived_oop_maps);
316 static CodeBlob* create(CodeBlob* archived_blob,
317 const char* name,
318 address archived_reloc_data,
319 ImmutableOopMapSet* archived_oop_maps);
320 };
321
322 //----------------------------------------------------------------------------------------------------
323 // RuntimeBlob: used for non-compiled method code (adapters, stubs, blobs)
324
325 class RuntimeBlob : public CodeBlob {
326 public:
327
328 // Creation
329 // a) simple CodeBlob
330 RuntimeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size)
331 : CodeBlob(name, kind, size, header_size)
332 {}
333
334 // b) full CodeBlob
335 // frame_complete is the offset from the beginning of the instructions
336 // to where the frame setup (from stackwalk viewpoint) is complete.
337 RuntimeBlob(
338 const char* name,
339 CodeBlobKind kind,
340 CodeBuffer* cb,
341 int size,
342 uint16_t header_size,
343 int16_t frame_complete,
344 int frame_size,
345 OopMapSet* oop_maps,
346 bool caller_must_gc_arguments = false
347 );
348
349 static void free(RuntimeBlob* blob);
350
351 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
352 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
353
354 class Vptr : public CodeBlob::Vptr {
355 };
356 };
357
358 class WhiteBox;
359 //----------------------------------------------------------------------------------------------------
360 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
361
362 class BufferBlob: public RuntimeBlob {
363 friend class VMStructs;
364 friend class AdapterBlob;
365 friend class VtableBlob;
366 friend class MethodHandlesAdapterBlob;
367 friend class UpcallStub;
368 friend class WhiteBox;
369
370 private:
371 // Creation support
372 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
373 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
374
375 void* operator new(size_t s, unsigned size) throw();
376
377 public:
378 // Creation
379 static BufferBlob* create(const char* name, uint buffer_size);
380 static BufferBlob* create(const char* name, CodeBuffer* cb);
381
382 static void free(BufferBlob* buf);
383
384 void print_on_impl(outputStream* st) const;
385 void print_value_on_impl(outputStream* st) const;
386
387 class Vptr : public RuntimeBlob::Vptr {
388 void print_on(const CodeBlob* instance, outputStream* st) const override {
389 ((const BufferBlob*)instance)->print_on_impl(st);
390 }
391 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
392 ((const BufferBlob*)instance)->print_value_on_impl(st);
393 }
394 };
395
396 static const Vptr _vpntr;
397 };
398
399
400 //----------------------------------------------------------------------------------------------------
401 // AdapterBlob: used to hold C2I/I2C adapters
402
403 class AdapterBlob: public BufferBlob {
404 public:
405 enum Entry {
406 I2C,
407 C2I,
408 C2I_Unverified,
409 C2I_No_Clinit_Check,
410 ENTRY_COUNT
411 };
412 private:
413 AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
414 // _i2c_offset is always 0 so no need to store it
415 int _c2i_offset;
416 int _c2i_unverified_offset;
417 int _c2i_no_clinit_check_offset;
418 public:
419 // Creation
420 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
421 address i2c_entry() { return code_begin(); }
422 address c2i_entry() { return i2c_entry() + _c2i_offset; }
423 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; }
424 address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; }
425 };
426
427 //---------------------------------------------------------------------------------------------------
428 class VtableBlob: public BufferBlob {
429 private:
430 VtableBlob(const char*, int);
431
432 void* operator new(size_t s, unsigned size) throw();
433
434 public:
435 // Creation
436 static VtableBlob* create(const char* name, int buffer_size);
437 };
438
439 //----------------------------------------------------------------------------------------------------
440 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
441
442 class MethodHandlesAdapterBlob: public BufferBlob {
443 private:
444 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
445
446 public:
447 // Creation
448 static MethodHandlesAdapterBlob* create(int buffer_size);
449 };
450
451
452 //----------------------------------------------------------------------------------------------------
453 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
454
455 class RuntimeStub: public RuntimeBlob {
456 friend class VMStructs;
457 private:
458 // Creation support
459 RuntimeStub(
460 const char* name,
461 CodeBuffer* cb,
462 int size,
463 int16_t frame_complete,
464 int frame_size,
465 OopMapSet* oop_maps,
466 bool caller_must_gc_arguments
467 );
468
469 void* operator new(size_t s, unsigned size) throw();
470
471 public:
472 static const int ENTRY_COUNT = 1;
473 // Creation
474 static RuntimeStub* new_runtime_stub(
475 const char* stub_name,
476 CodeBuffer* cb,
477 int16_t frame_complete,
478 int frame_size,
479 OopMapSet* oop_maps,
480 bool caller_must_gc_arguments,
481 bool alloc_fail_is_fatal=true
482 );
483
484 static void free(RuntimeStub* stub) { RuntimeBlob::free(stub); }
485
486 address entry_point() const { return code_begin(); }
487
488 void print_on_impl(outputStream* st) const;
489 void print_value_on_impl(outputStream* st) const;
490
491 class Vptr : public RuntimeBlob::Vptr {
492 void print_on(const CodeBlob* instance, outputStream* st) const override {
493 instance->as_runtime_stub()->print_on_impl(st);
494 }
495 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
496 instance->as_runtime_stub()->print_value_on_impl(st);
497 }
498 };
499
500 static const Vptr _vpntr;
501 };
502
503
504 //----------------------------------------------------------------------------------------------------
505 // Super-class for all blobs that exist in only one instance. Implements default behaviour.
506
507 class SingletonBlob: public RuntimeBlob {
508 friend class VMStructs;
509
510 protected:
511 void* operator new(size_t s, unsigned size, bool alloc_fail_is_fatal=true) throw();
512
513 public:
514 SingletonBlob(
515 const char* name,
516 CodeBlobKind kind,
517 CodeBuffer* cb,
518 int size,
519 uint16_t header_size,
520 int frame_size,
521 OopMapSet* oop_maps
522 )
523 : RuntimeBlob(name, kind, cb, size, header_size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
524 {};
525
526 address entry_point() { return code_begin(); }
527
528 void print_on_impl(outputStream* st) const;
529 void print_value_on_impl(outputStream* st) const;
530
531 class Vptr : public RuntimeBlob::Vptr {
532 void print_on(const CodeBlob* instance, outputStream* st) const override {
533 ((const SingletonBlob*)instance)->print_on_impl(st);
534 }
535 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
536 ((const SingletonBlob*)instance)->print_value_on_impl(st);
537 }
538 };
539
540 static const Vptr _vpntr;
541 };
542
543
544 //----------------------------------------------------------------------------------------------------
545 // DeoptimizationBlob
546
547 class DeoptimizationBlob: public SingletonBlob {
548 friend class VMStructs;
549 friend class JVMCIVMStructs;
550 private:
551 int _unpack_offset;
552 int _unpack_with_exception;
553 int _unpack_with_reexecution;
554
555 int _unpack_with_exception_in_tls;
556
557 #if INCLUDE_JVMCI
558 // Offsets when JVMCI calls uncommon_trap.
559 int _uncommon_trap_offset;
560 int _implicit_exception_uncommon_trap_offset;
561 #endif
562
563 // Creation support
564 DeoptimizationBlob(
565 CodeBuffer* cb,
566 int size,
567 OopMapSet* oop_maps,
568 int unpack_offset,
569 int unpack_with_exception_offset,
570 int unpack_with_reexecution_offset,
571 int frame_size
572 );
573
574 public:
575 static const int ENTRY_COUNT = 4 JVMTI_ONLY(+ 2);
576 // Creation
577 static DeoptimizationBlob* create(
578 CodeBuffer* cb,
579 OopMapSet* oop_maps,
580 int unpack_offset,
581 int unpack_with_exception_offset,
582 int unpack_with_reexecution_offset,
583 int frame_size
584 );
585
586 address unpack() const { return code_begin() + _unpack_offset; }
587 address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }
588 address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }
589
590 // Alternate entry point for C1 where the exception and issuing pc
591 // are in JavaThread::_exception_oop and JavaThread::_exception_pc
592 // instead of being in registers. This is needed because C1 doesn't
593 // model exception paths in a way that keeps these registers free so
594 // there may be live values in those registers during deopt.
595 void set_unpack_with_exception_in_tls_offset(int offset) {
596 _unpack_with_exception_in_tls = offset;
597 assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
598 }
599 address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }
600
601 #if INCLUDE_JVMCI
602 // Offsets when JVMCI calls uncommon_trap.
603 void set_uncommon_trap_offset(int offset) {
604 _uncommon_trap_offset = offset;
605 assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");
606 }
607 address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; }
608
609 void set_implicit_exception_uncommon_trap_offset(int offset) {
610 _implicit_exception_uncommon_trap_offset = offset;
611 assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob");
612 }
613 address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }
614 #endif // INCLUDE_JVMCI
615
616 void print_value_on_impl(outputStream* st) const;
617
618 class Vptr : public SingletonBlob::Vptr {
619 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
620 ((const DeoptimizationBlob*)instance)->print_value_on_impl(st);
621 }
622 };
623
624 static const Vptr _vpntr;
625 };
626
627
628 //----------------------------------------------------------------------------------------------------
629 // UncommonTrapBlob (currently only used by Compiler 2)
630
631 #ifdef COMPILER2
632
633 class UncommonTrapBlob: public SingletonBlob {
634 private:
635 // Creation support
636 UncommonTrapBlob(
637 CodeBuffer* cb,
638 int size,
639 OopMapSet* oop_maps,
640 int frame_size
641 );
642
643 public:
644 // Creation
645 static UncommonTrapBlob* create(
646 CodeBuffer* cb,
647 OopMapSet* oop_maps,
648 int frame_size
649 );
650 };
651
652
653 //----------------------------------------------------------------------------------------------------
654 // ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2)
655
656 class ExceptionBlob: public SingletonBlob {
657 private:
658 // Creation support
659 ExceptionBlob(
660 CodeBuffer* cb,
661 int size,
662 OopMapSet* oop_maps,
663 int frame_size
664 );
665
666 public:
667 // Creation
668 static ExceptionBlob* create(
669 CodeBuffer* cb,
670 OopMapSet* oop_maps,
671 int frame_size
672 );
673
674 void post_restore_impl() {
675 trace_new_stub(this, "ExceptionBlob");
676 }
677
678 class Vptr : public SingletonBlob::Vptr {
679 void post_restore(CodeBlob* instance) const override {
680 ((ExceptionBlob*)instance)->post_restore_impl();
681 }
682 };
683
684 static const Vptr _vpntr;
685 };
686 #endif // COMPILER2
687
688
689 //----------------------------------------------------------------------------------------------------
690 // SafepointBlob: handles illegal_instruction exceptions during a safepoint
691
692 class SafepointBlob: public SingletonBlob {
693 private:
694 // Creation support
695 SafepointBlob(
696 CodeBuffer* cb,
697 int size,
698 OopMapSet* oop_maps,
699 int frame_size
700 );
701
702 public:
703 static const int ENTRY_COUNT = 1;
704 // Creation
705 static SafepointBlob* create(
706 CodeBuffer* cb,
707 OopMapSet* oop_maps,
708 int frame_size
709 );
710 };
711
712 //----------------------------------------------------------------------------------------------------
713
714 class UpcallLinker;
715
716 // A (Panama) upcall stub. Not used by JNI.
717 class UpcallStub: public RuntimeBlob {
718 friend class VMStructs;
719 friend class UpcallLinker;
720 private:
721 jobject _receiver;
722 ByteSize _frame_data_offset;
723
724 UpcallStub(const char* name, CodeBuffer* cb, int size, jobject receiver, ByteSize frame_data_offset);
725
726 void* operator new(size_t s, unsigned size) throw();
727
728 struct FrameData {
729 JavaFrameAnchor jfa;
730 JavaThread* thread;
731 JNIHandleBlock* old_handles;
732 JNIHandleBlock* new_handles;
733 };
734
735 // defined in frame_ARCH.cpp
736 FrameData* frame_data_for_frame(const frame& frame) const;
737 public:
738 // Creation
739 static UpcallStub* create(const char* name, CodeBuffer* cb, jobject receiver, ByteSize frame_data_offset);
740
741 static void free(UpcallStub* blob);
742
743 jobject receiver() { return _receiver; }
744
745 JavaFrameAnchor* jfa_for_frame(const frame& frame) const;
746
747 // GC support
748 void oops_do(OopClosure* f, const frame& frame);
749
750 void print_on_impl(outputStream* st) const;
751 void print_value_on_impl(outputStream* st) const;
752
753 class Vptr : public RuntimeBlob::Vptr {
754 void print_on(const CodeBlob* instance, outputStream* st) const override {
755 instance->as_upcall_stub()->print_on_impl(st);
756 }
757 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
758 instance->as_upcall_stub()->print_value_on_impl(st);
759 }
760 };
761
762 static const Vptr _vpntr;
763 };
764
765 #endif // SHARE_CODE_CODEBLOB_HPP