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