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