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() {
178 assert(_oop_maps == nullptr, "Not flushed");
179 }
180
181 // Returns the space needed for CodeBlob
182 static unsigned int allocation_size(CodeBuffer* cb, int header_size);
183 static unsigned int align_code_offset(int offset);
184
185 // Deletion
186 void purge();
187
188 // Typing
189 bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; }
190 bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; }
191 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
192 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
193 #ifdef COMPILER2
194 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
195 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
196 #else
197 bool is_uncommon_trap_stub() const { return false; }
198 bool is_exception_stub() const { return false; }
199 #endif
200 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
201 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
202 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
203 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
204 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
205
206 // Casting
207 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
208 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
209 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
210 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
211 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
212 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
213 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
214 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
215 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
216 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
217
218 // Boundaries
219 address header_begin() const { return (address) this; }
220 address header_end() const { return ((address) this) + _header_size; }
221 address content_begin() const { return (address) header_begin() + _content_offset; }
222 address content_end() const { return (address) header_begin() + _data_offset; }
223 address code_begin() const { return (address) header_begin() + _code_offset; }
224 address code_end() const { return (address) header_begin() + _data_offset; }
225 address data_begin() const { return (address) header_begin() + _data_offset; }
226 address data_end() const { return (address) header_begin() + _size; }
227 address blob_end() const { return (address) header_begin() + _size; }
228 // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor
229
230 int mutable_data_size() const { return _mutable_data_size; }
231 address mutable_data_begin() const { return _mutable_data; }
232 address mutable_data_end() const { return _mutable_data + _mutable_data_size; }
233
234 relocInfo* relocation_begin() const { return (relocInfo*)_mutable_data; }
235 relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); }
236
237 // Offsets
238 int content_offset() const { return _content_offset; }
239 int code_offset() const { return _code_offset; }
240
241 // This field holds the beginning of the const section in the old code buffer.
242 // It is needed to fix relocations of pc-relative loads when resizing the
243 // the constant pool or moving it.
244 S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; })
245 void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) }
246
247 // Sizes
248 int size() const { return _size; }
249 int header_size() const { return _header_size; }
250 int relocation_size() const { return _relocation_size; }
251 int content_size() const { return pointer_delta_as_int(content_end(), content_begin()); }
252 int code_size() const { return pointer_delta_as_int(code_end(), code_begin()); }
253
254 // Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed
255 void adjust_size(size_t used) {
256 _size = (int)used;
257 _data_offset = _size;
258 }
259
260 // Containment
261 bool blob_contains(address addr) const { return header_begin() <= addr && addr < blob_end(); }
262 bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }
263 bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); }
264 bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe &&
265 code_contains(addr) && addr >= code_begin() + _frame_complete_offset; }
266 int frame_complete_offset() const { return _frame_complete_offset; }
267
268 // OopMap for frame
269 ImmutableOopMapSet* oop_maps() const { return _oop_maps; }
270 void set_oop_maps(OopMapSet* p);
271 void set_oop_maps(ImmutableOopMapSet* p) { _oop_maps = p; }
272
273 const ImmutableOopMap* oop_map_for_slot(int slot, address return_address) const;
274 const ImmutableOopMap* oop_map_for_return_address(address return_address) const;
275
276 // Frame support. Sizes are in word units.
277 int frame_size() const { return _frame_size; }
278 void set_frame_size(int size) { _frame_size = size; }
279
280 // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
281 bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
282
283 // Naming
284 const char* name() const { return _name; }
285 void set_name(const char* name) { _name = name; }
286
287 // Debugging
288 void verify();
289 void print() const;
290 void print_on(outputStream* st) const;
291 void print_value_on(outputStream* st) const;
292
293 void dump_for_addr(address addr, outputStream* st, bool verbose) const;
294 void print_code_on(outputStream* st);
295
296 // Print to stream, any comments associated with offset.
297 void print_block_comment(outputStream* stream, address block_begin) const;
298
299 #ifndef PRODUCT
300 AsmRemarks &asm_remarks() { return _asm_remarks; }
301 DbgStrings &dbg_strings() { return _dbg_strings; }
302
303 void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); }
304 void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); }
305 #endif
306
307 void copy_to(address buffer) {
308 memcpy(buffer, this, this->size());
309 }
310
311 // methods to archive a blob into AOT code cache
312 void prepare_for_archiving();
313 static void archive_blob(CodeBlob* blob, address archive_buffer);
314
315 // methods to restore a blob from AOT code cache into the CodeCache
316 void post_restore();
317 CodeBlob* restore(address code_cache_buffer, const char* name, address archived_reloc_data, ImmutableOopMapSet* archived_oop_maps);
318 static CodeBlob* create(CodeBlob* archived_blob,
319 const char* name,
320 address archived_reloc_data,
321 ImmutableOopMapSet* archived_oop_maps);
322 };
323
324 //----------------------------------------------------------------------------------------------------
325 // RuntimeBlob: used for non-compiled method code (adapters, stubs, blobs)
326
327 class RuntimeBlob : public CodeBlob {
328 public:
329
330 // Creation
331 // a) simple CodeBlob
332 RuntimeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size)
333 : CodeBlob(name, kind, size, header_size)
334 {}
335
336 // b) full CodeBlob
337 // frame_complete is the offset from the beginning of the instructions
338 // to where the frame setup (from stackwalk viewpoint) is complete.
339 RuntimeBlob(
340 const char* name,
341 CodeBlobKind kind,
342 CodeBuffer* cb,
343 int size,
344 uint16_t header_size,
345 int16_t frame_complete,
346 int frame_size,
347 OopMapSet* oop_maps,
348 bool caller_must_gc_arguments = false
349 );
350
351 static void free(RuntimeBlob* blob);
352
353 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
354 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
355
356 class Vptr : public CodeBlob::Vptr {
357 };
358 };
359
360 class WhiteBox;
361 //----------------------------------------------------------------------------------------------------
362 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
363
364 class BufferBlob: public RuntimeBlob {
365 friend class VMStructs;
366 friend class AdapterBlob;
367 friend class VtableBlob;
368 friend class MethodHandlesAdapterBlob;
369 friend class UpcallStub;
370 friend class WhiteBox;
371
372 private:
373 // Creation support
374 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
375 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
376
377 void* operator new(size_t s, unsigned size) throw();
378
379 public:
380 // Creation
381 static BufferBlob* create(const char* name, uint buffer_size);
382 static BufferBlob* create(const char* name, CodeBuffer* cb);
383
384 static void free(BufferBlob* buf);
385
386 void print_on_impl(outputStream* st) const;
387 void print_value_on_impl(outputStream* st) const;
388
389 class Vptr : public RuntimeBlob::Vptr {
390 void print_on(const CodeBlob* instance, outputStream* st) const override {
391 ((const BufferBlob*)instance)->print_on_impl(st);
392 }
393 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
394 ((const BufferBlob*)instance)->print_value_on_impl(st);
395 }
396 };
397
398 static const Vptr _vpntr;
399 };
400
401
402 //----------------------------------------------------------------------------------------------------
403 // AdapterBlob: used to hold C2I/I2C adapters
404
405 class AdapterBlob: public BufferBlob {
406 public:
407 enum Entry {
408 I2C,
409 C2I,
410 C2I_Unverified,
411 C2I_No_Clinit_Check,
412 ENTRY_COUNT
413 };
414 private:
415 AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
416 // _i2c_offset is always 0 so no need to store it
417 int _c2i_offset;
418 int _c2i_unverified_offset;
419 int _c2i_no_clinit_check_offset;
420 public:
421 // Creation
422 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
423 address i2c_entry() { return code_begin(); }
424 address c2i_entry() { return i2c_entry() + _c2i_offset; }
425 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; }
426 address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; }
427 };
428
429 //---------------------------------------------------------------------------------------------------
430 class VtableBlob: public BufferBlob {
431 private:
432 VtableBlob(const char*, int);
433
434 void* operator new(size_t s, unsigned size) throw();
435
436 public:
437 // Creation
438 static VtableBlob* create(const char* name, int buffer_size);
439 };
440
441 //----------------------------------------------------------------------------------------------------
442 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
443
444 class MethodHandlesAdapterBlob: public BufferBlob {
445 private:
446 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
447
448 public:
449 // Creation
450 static MethodHandlesAdapterBlob* create(int buffer_size);
451 };
452
453
454 //----------------------------------------------------------------------------------------------------
455 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
456
457 class RuntimeStub: public RuntimeBlob {
458 friend class VMStructs;
459 private:
460 // Creation support
461 RuntimeStub(
462 const char* name,
463 CodeBuffer* cb,
464 int size,
465 int16_t frame_complete,
466 int frame_size,
467 OopMapSet* oop_maps,
468 bool caller_must_gc_arguments
469 );
470
471 void* operator new(size_t s, unsigned size) throw();
472
473 public:
474 static const int ENTRY_COUNT = 1;
475 // Creation
476 static RuntimeStub* new_runtime_stub(
477 const char* stub_name,
478 CodeBuffer* cb,
479 int16_t frame_complete,
480 int frame_size,
481 OopMapSet* oop_maps,
482 bool caller_must_gc_arguments,
483 bool alloc_fail_is_fatal=true
484 );
485
486 static void free(RuntimeStub* stub) { RuntimeBlob::free(stub); }
487
488 address entry_point() const { return code_begin(); }
489
490 void print_on_impl(outputStream* st) const;
491 void print_value_on_impl(outputStream* st) const;
492
493 class Vptr : public RuntimeBlob::Vptr {
494 void print_on(const CodeBlob* instance, outputStream* st) const override {
495 instance->as_runtime_stub()->print_on_impl(st);
496 }
497 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
498 instance->as_runtime_stub()->print_value_on_impl(st);
499 }
500 };
501
502 static const Vptr _vpntr;
503 };
504
505
506 //----------------------------------------------------------------------------------------------------
507 // Super-class for all blobs that exist in only one instance. Implements default behaviour.
508
509 class SingletonBlob: public RuntimeBlob {
510 friend class VMStructs;
511
512 protected:
513 void* operator new(size_t s, unsigned size, bool alloc_fail_is_fatal=true) throw();
514
515 public:
516 SingletonBlob(
517 const char* name,
518 CodeBlobKind kind,
519 CodeBuffer* cb,
520 int size,
521 uint16_t header_size,
522 int frame_size,
523 OopMapSet* oop_maps
524 )
525 : RuntimeBlob(name, kind, cb, size, header_size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
526 {};
527
528 address entry_point() { return code_begin(); }
529
530 void print_on_impl(outputStream* st) const;
531 void print_value_on_impl(outputStream* st) const;
532
533 class Vptr : public RuntimeBlob::Vptr {
534 void print_on(const CodeBlob* instance, outputStream* st) const override {
535 ((const SingletonBlob*)instance)->print_on_impl(st);
536 }
537 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
538 ((const SingletonBlob*)instance)->print_value_on_impl(st);
539 }
540 };
541
542 static const Vptr _vpntr;
543 };
544
545
546 //----------------------------------------------------------------------------------------------------
547 // DeoptimizationBlob
548
549 class DeoptimizationBlob: public SingletonBlob {
550 friend class VMStructs;
551 friend class JVMCIVMStructs;
552 private:
553 int _unpack_offset;
554 int _unpack_with_exception;
555 int _unpack_with_reexecution;
556
557 int _unpack_with_exception_in_tls;
558
559 #if INCLUDE_JVMCI
560 // Offsets when JVMCI calls uncommon_trap.
561 int _uncommon_trap_offset;
562 int _implicit_exception_uncommon_trap_offset;
563 #endif
564
565 // Creation support
566 DeoptimizationBlob(
567 CodeBuffer* cb,
568 int size,
569 OopMapSet* oop_maps,
570 int unpack_offset,
571 int unpack_with_exception_offset,
572 int unpack_with_reexecution_offset,
573 int frame_size
574 );
575
576 public:
577 static const int ENTRY_COUNT = 4 JVMTI_ONLY(+ 2);
578 // Creation
579 static DeoptimizationBlob* create(
580 CodeBuffer* cb,
581 OopMapSet* oop_maps,
582 int unpack_offset,
583 int unpack_with_exception_offset,
584 int unpack_with_reexecution_offset,
585 int frame_size
586 );
587
588 address unpack() const { return code_begin() + _unpack_offset; }
589 address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }
590 address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }
591
592 // Alternate entry point for C1 where the exception and issuing pc
593 // are in JavaThread::_exception_oop and JavaThread::_exception_pc
594 // instead of being in registers. This is needed because C1 doesn't
595 // model exception paths in a way that keeps these registers free so
596 // there may be live values in those registers during deopt.
597 void set_unpack_with_exception_in_tls_offset(int offset) {
598 _unpack_with_exception_in_tls = offset;
599 assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
600 }
601 address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }
602
603 #if INCLUDE_JVMCI
604 // Offsets when JVMCI calls uncommon_trap.
605 void set_uncommon_trap_offset(int offset) {
606 _uncommon_trap_offset = offset;
607 assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");
608 }
609 address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; }
610
611 void set_implicit_exception_uncommon_trap_offset(int offset) {
612 _implicit_exception_uncommon_trap_offset = offset;
613 assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob");
614 }
615 address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }
616 #endif // INCLUDE_JVMCI
617
618 void print_value_on_impl(outputStream* st) const;
619
620 class Vptr : public SingletonBlob::Vptr {
621 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
622 ((const DeoptimizationBlob*)instance)->print_value_on_impl(st);
623 }
624 };
625
626 static const Vptr _vpntr;
627 };
628
629
630 //----------------------------------------------------------------------------------------------------
631 // UncommonTrapBlob (currently only used by Compiler 2)
632
633 #ifdef COMPILER2
634
635 class UncommonTrapBlob: public SingletonBlob {
636 private:
637 // Creation support
638 UncommonTrapBlob(
639 CodeBuffer* cb,
640 int size,
641 OopMapSet* oop_maps,
642 int frame_size
643 );
644
645 public:
646 // Creation
647 static UncommonTrapBlob* create(
648 CodeBuffer* cb,
649 OopMapSet* oop_maps,
650 int frame_size
651 );
652 };
653
654
655 //----------------------------------------------------------------------------------------------------
656 // ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2)
657
658 class ExceptionBlob: public SingletonBlob {
659 private:
660 // Creation support
661 ExceptionBlob(
662 CodeBuffer* cb,
663 int size,
664 OopMapSet* oop_maps,
665 int frame_size
666 );
667
668 public:
669 // Creation
670 static ExceptionBlob* create(
671 CodeBuffer* cb,
672 OopMapSet* oop_maps,
673 int frame_size
674 );
675
676 void post_restore_impl() {
677 trace_new_stub(this, "ExceptionBlob");
678 }
679
680 class Vptr : public SingletonBlob::Vptr {
681 void post_restore(CodeBlob* instance) const override {
682 ((ExceptionBlob*)instance)->post_restore_impl();
683 }
684 };
685
686 static const Vptr _vpntr;
687 };
688 #endif // COMPILER2
689
690
691 //----------------------------------------------------------------------------------------------------
692 // SafepointBlob: handles illegal_instruction exceptions during a safepoint
693
694 class SafepointBlob: public SingletonBlob {
695 private:
696 // Creation support
697 SafepointBlob(
698 CodeBuffer* cb,
699 int size,
700 OopMapSet* oop_maps,
701 int frame_size
702 );
703
704 public:
705 static const int ENTRY_COUNT = 1;
706 // Creation
707 static SafepointBlob* create(
708 CodeBuffer* cb,
709 OopMapSet* oop_maps,
710 int frame_size
711 );
712 };
713
714 //----------------------------------------------------------------------------------------------------
715
716 class UpcallLinker;
717
718 // A (Panama) upcall stub. Not used by JNI.
719 class UpcallStub: public RuntimeBlob {
720 friend class VMStructs;
721 friend class UpcallLinker;
722 private:
723 jobject _receiver;
724 ByteSize _frame_data_offset;
725
726 UpcallStub(const char* name, CodeBuffer* cb, int size, jobject receiver, ByteSize frame_data_offset);
727
728 void* operator new(size_t s, unsigned size) throw();
729
730 struct FrameData {
731 JavaFrameAnchor jfa;
732 JavaThread* thread;
733 JNIHandleBlock* old_handles;
734 JNIHandleBlock* new_handles;
735 };
736
737 // defined in frame_ARCH.cpp
738 FrameData* frame_data_for_frame(const frame& frame) const;
739 public:
740 // Creation
741 static UpcallStub* create(const char* name, CodeBuffer* cb, jobject receiver, ByteSize frame_data_offset);
742
743 static void free(UpcallStub* blob);
744
745 jobject receiver() { return _receiver; }
746
747 JavaFrameAnchor* jfa_for_frame(const frame& frame) const;
748
749 // GC support
750 void oops_do(OopClosure* f, const frame& frame);
751
752 void print_on_impl(outputStream* st) const;
753 void print_value_on_impl(outputStream* st) const;
754
755 class Vptr : public RuntimeBlob::Vptr {
756 void print_on(const CodeBlob* instance, outputStream* st) const override {
757 instance->as_upcall_stub()->print_on_impl(st);
758 }
759 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
760 instance->as_upcall_stub()->print_value_on_impl(st);
761 }
762 };
763
764 static const Vptr _vpntr;
765 };
766
767 #endif // SHARE_CODE_CODEBLOB_HPP