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 // RuntimeStub : Call to VM runtime methods
64 // SingletonBlob : Super-class for all blobs that exist in only one instance
65 // DeoptimizationBlob : Used for deoptimization
66 // SafepointBlob : Used to handle illegal instruction exceptions
67 // ExceptionBlob : Used for stack unrolling
68 // UncommonTrapBlob : Used to handle uncommon traps
69 // UpcallStub : Used for upcalls from native code
70 //
71 //
72 // Layout in the CodeCache:
73 // - header
74 // - content space
75 // - instruction space
76 // Outside of the CodeCache:
77 // - mutable_data
78 // - relocation info
79 // - additional data for subclasses
80
81 enum class CodeBlobKind : u1 {
82 None,
83 Nmethod,
84 Buffer,
85 Adapter,
86 Vtable,
87 MHAdapter,
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 BufferBlob;
103 class AdapterBlob;
104 class SingletonBlob;
105 class ExceptionBlob;
106 class DeoptimizationBlob;
107 class SafepointBlob;
202 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
203 // singleton blobs are never directly implemented
204 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
205 #ifdef COMPILER2
206 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
207 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
208 #else
209 bool is_uncommon_trap_stub() const { return false; }
210 bool is_exception_stub() const { return false; }
211 #endif
212 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
213 bool is_singleton_blob() const {
214 return (is_deoptimization_stub() ||
215 is_uncommon_trap_stub() ||
216 is_exception_stub() ||
217 is_safepoint_stub());
218 }
219 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
220 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
221 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
222 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
223
224 // Casting
225 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
226 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
227 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
228 // we may want to force an actual buffer blob or subtype instance
229 BufferBlob* as_buffer_blob(bool strict = true) const { assert(is_buffer_blob(strict), "must be %sbuffer blob", (strict ? "strict " : "")); return (BufferBlob*) this; }
230 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
231 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
232 // this will always return a subtype instance
233 SingletonBlob* as_singleton_blob() const { assert(is_singleton_blob(), "must be singleton blob"); return (SingletonBlob*) this; }
234 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
235 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
236 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
237 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
238 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
239
240 // Boundaries
241 address header_begin() const { return (address) this; }
372 );
373
374 static void free(RuntimeBlob* blob);
375
376 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
377 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
378
379 class Vptr : public CodeBlob::Vptr {
380 };
381 };
382
383 class WhiteBox;
384 //----------------------------------------------------------------------------------------------------
385 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
386
387 class BufferBlob: public RuntimeBlob {
388 friend class VMStructs;
389 friend class AdapterBlob;
390 friend class VtableBlob;
391 friend class MethodHandlesAdapterBlob;
392 friend class UpcallStub;
393 friend class WhiteBox;
394
395 private:
396 // Creation support
397 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
398 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
399
400 void* operator new(size_t s, unsigned size) throw();
401
402 public:
403 // Creation
404 static BufferBlob* create(const char* name, uint buffer_size);
405 static BufferBlob* create(const char* name, CodeBuffer* cb);
406
407 static void free(BufferBlob* buf);
408
409 void print_on_impl(outputStream* st) const;
410 void print_value_on_impl(outputStream* st) const;
411
412 class Vptr : public RuntimeBlob::Vptr {
413 void print_on(const CodeBlob* instance, outputStream* st) const override {
414 instance->as_buffer_blob(false)->print_on_impl(st);
415 }
416 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
417 instance->as_buffer_blob(false)->print_value_on_impl(st);
418 }
419 };
420
421 static const Vptr _vpntr;
422 };
423
424
425 //----------------------------------------------------------------------------------------------------
426 // AdapterBlob: used to hold C2I/I2C adapters
427
428 class AdapterBlob: public BufferBlob {
429 public:
430 enum Entry {
431 I2C,
432 C2I,
433 C2I_Unverified,
434 C2I_No_Clinit_Check,
435 ENTRY_COUNT
436 };
437 private:
438 AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
439 // _i2c_offset is always 0 so no need to store it
440 int _c2i_offset;
441 int _c2i_unverified_offset;
442 int _c2i_no_clinit_check_offset;
443 public:
444 // Creation
445 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
446 address i2c_entry() { return code_begin(); }
447 address c2i_entry() { return i2c_entry() + _c2i_offset; }
448 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_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 //----------------------------------------------------------------------------------------------------
478 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
479
480 class RuntimeStub: public RuntimeBlob {
481 friend class VMStructs;
482 private:
483 // Creation support
484 RuntimeStub(
485 const char* name,
486 CodeBuffer* cb,
487 int size,
488 int16_t frame_complete,
489 int frame_size,
490 OopMapSet* oop_maps,
491 bool caller_must_gc_arguments
492 );
493
494 void* operator new(size_t s, unsigned size) throw();
495
|
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;
204 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
205 // singleton blobs are never directly implemented
206 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
207 #ifdef COMPILER2
208 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
209 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
210 #else
211 bool is_uncommon_trap_stub() const { return false; }
212 bool is_exception_stub() const { return false; }
213 #endif
214 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
215 bool is_singleton_blob() const {
216 return (is_deoptimization_stub() ||
217 is_uncommon_trap_stub() ||
218 is_exception_stub() ||
219 is_safepoint_stub());
220 }
221 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
222 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
223 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
224 bool is_buffered_inline_type_blob() const { return _kind == CodeBlobKind::BufferedInlineType; }
225 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
226
227 // Casting
228 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
229 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
230 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
231 // we may want to force an actual buffer blob or subtype instance
232 BufferBlob* as_buffer_blob(bool strict = true) const { assert(is_buffer_blob(strict), "must be %sbuffer blob", (strict ? "strict " : "")); return (BufferBlob*) this; }
233 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
234 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
235 // this will always return a subtype instance
236 SingletonBlob* as_singleton_blob() const { assert(is_singleton_blob(), "must be singleton blob"); return (SingletonBlob*) this; }
237 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
238 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
239 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
240 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
241 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
242
243 // Boundaries
244 address header_begin() const { return (address) this; }
375 );
376
377 static void free(RuntimeBlob* blob);
378
379 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
380 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
381
382 class Vptr : public CodeBlob::Vptr {
383 };
384 };
385
386 class WhiteBox;
387 //----------------------------------------------------------------------------------------------------
388 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
389
390 class BufferBlob: public RuntimeBlob {
391 friend class VMStructs;
392 friend class AdapterBlob;
393 friend class VtableBlob;
394 friend class MethodHandlesAdapterBlob;
395 friend class BufferedInlineTypeBlob;
396 friend class UpcallStub;
397 friend class WhiteBox;
398
399 private:
400 // Creation support
401 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
402 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
403 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);
404
405 void* operator new(size_t s, unsigned size) throw();
406
407 public:
408 // Creation
409 static BufferBlob* create(const char* name, uint buffer_size);
410 static BufferBlob* create(const char* name, CodeBuffer* cb);
411
412 static void free(BufferBlob* buf);
413
414 void print_on_impl(outputStream* st) const;
415 void print_value_on_impl(outputStream* st) const;
416
417 class Vptr : public RuntimeBlob::Vptr {
418 void print_on(const CodeBlob* instance, outputStream* st) const override {
419 instance->as_buffer_blob(false)->print_on_impl(st);
420 }
421 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
422 instance->as_buffer_blob(false)->print_value_on_impl(st);
423 }
424 };
425
426 static const Vptr _vpntr;
427 };
428
429
430 //----------------------------------------------------------------------------------------------------
431 // AdapterBlob: used to hold C2I/I2C adapters
432
433 class AdapterBlob: public BufferBlob {
434 public:
435 enum Entry {
436 I2C,
437 C2I,
438 C2I_Inline,
439 C2I_Inline_RO,
440 C2I_Unverified,
441 C2I_Unverified_Inline,
442 C2I_No_Clinit_Check,
443 ENTRY_COUNT
444 };
445 private:
446 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);
447
448 // _i2c_offset is always 0 so no need to store it
449 int _c2i_offset;
450 int _c2i_inline_offset;
451 int _c2i_inline_ro_offset;
452 int _c2i_unverified_offset;
453 int _c2i_unverified_inline_offset;
454 int _c2i_no_clinit_check_offset;
455 public:
456 // Creation
457 static AdapterBlob* create(CodeBuffer* cb,
458 int entry_offset[ENTRY_COUNT],
459 int frame_complete,
460 int frame_size,
461 OopMapSet* oop_maps,
462 bool caller_must_gc_arguments = false);
463
464 bool caller_must_gc_arguments(JavaThread* thread) const { return true; }
465 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
466 address i2c_entry() { return code_begin(); }
467 address c2i_entry() { return i2c_entry() + _c2i_offset; }
468 address c2i_inline_entry() { return i2c_entry() + _c2i_inline_offset; }
469 address c2i_inline_ro_entry() { return i2c_entry() + _c2i_inline_ro_offset; }
470 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; }
471 address c2i_unverified_inline_entry() { return i2c_entry() + _c2i_unverified_inline_offset; }
472 address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; }
473 };
474
475 //---------------------------------------------------------------------------------------------------
476 class VtableBlob: public BufferBlob {
477 private:
478 VtableBlob(const char*, int);
479
480 void* operator new(size_t s, unsigned size) throw();
481
482 public:
483 // Creation
484 static VtableBlob* create(const char* name, int buffer_size);
485 };
486
487 //----------------------------------------------------------------------------------------------------
488 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
489
490 class MethodHandlesAdapterBlob: public BufferBlob {
491 private:
492 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
493
494 public:
495 // Creation
496 static MethodHandlesAdapterBlob* create(int buffer_size);
497 };
498
499 //----------------------------------------------------------------------------------------------------
500 // BufferedInlineTypeBlob : used for pack/unpack handlers
501
502 class BufferedInlineTypeBlob: public BufferBlob {
503 private:
504 const int _pack_fields_off;
505 const int _pack_fields_jobject_off;
506 const int _unpack_fields_off;
507
508 BufferedInlineTypeBlob(int size, CodeBuffer* cb, int pack_fields_off, int pack_fields_jobject_off, int unpack_fields_off);
509
510 public:
511 // Creation
512 static BufferedInlineTypeBlob* create(CodeBuffer* cb, int pack_fields_off, int pack_fields_jobject_off, int unpack_fields_off);
513
514 address pack_fields() const { return code_begin() + _pack_fields_off; }
515 address pack_fields_jobject() const { return code_begin() + _pack_fields_jobject_off; }
516 address unpack_fields() const { return code_begin() + _unpack_fields_off; }
517 };
518
519 //----------------------------------------------------------------------------------------------------
520 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
521
522 class RuntimeStub: public RuntimeBlob {
523 friend class VMStructs;
524 private:
525 // Creation support
526 RuntimeStub(
527 const char* name,
528 CodeBuffer* cb,
529 int size,
530 int16_t frame_complete,
531 int frame_size,
532 OopMapSet* oop_maps,
533 bool caller_must_gc_arguments
534 );
535
536 void* operator new(size_t s, unsigned size) throw();
537
|