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 NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
49 All = 3, // All types (No code cache segmentation)
50 NumTypes = 4 // Number of CodeBlobTypes
51 };
52
53 // CodeBlob - superclass for all entries in the CodeCache.
54 //
55 // Subtypes are:
56 // nmethod : JIT Compiled Java methods
57 // RuntimeBlob : Non-compiled method code; generated glue code
58 // BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc.
59 // AdapterBlob : Used to hold C2I/I2C adapters
60 // VtableBlob : Used for holding vtable chunks
61 // MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
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 RuntimeStub,
88 Deoptimization,
89 Safepoint,
90 #ifdef COMPILER2
91 Exception,
92 UncommonTrap,
93 #endif
94 Upcall,
95 Number_Of_Kinds
96 };
97
98 class UpcallStub; // for as_upcall_stub()
99 class RuntimeStub; // for as_runtime_stub()
100 class JavaFrameAnchor; // for UpcallStub::jfa_for_frame
101 class BufferBlob;
102 class AdapterBlob;
103 class SingletonBlob;
104 class ExceptionBlob;
105 class DeoptimizationBlob;
106 class SafepointBlob;
201 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
202 // singleton blobs are never directly implemented
203 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
204 #ifdef COMPILER2
205 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
206 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
207 #else
208 bool is_uncommon_trap_stub() const { return false; }
209 bool is_exception_stub() const { return false; }
210 #endif
211 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
212 bool is_singleton_blob() const {
213 return (is_deoptimization_stub() ||
214 is_uncommon_trap_stub() ||
215 is_exception_stub() ||
216 is_safepoint_stub());
217 }
218 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
219 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
220 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
221 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
222
223 // Casting
224 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
225 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
226 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
227 // we may want to force an actual buffer blob or subtype instance
228 BufferBlob* as_buffer_blob(bool strict = true) const { assert(is_buffer_blob(), "must be %sbuffer blob", (strict ? "strict " : "")); return (BufferBlob*) this; }
229 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
230 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
231 // this will always return a subtype instance
232 SingletonBlob* as_singleton_blob() const { assert(is_singleton_blob(), "must be singleton blob"); return (SingletonBlob*) this; }
233 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
234 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
235 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
236 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
237 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
238
239 // Boundaries
240 address header_begin() const { return (address) this; }
371 );
372
373 static void free(RuntimeBlob* blob);
374
375 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
376 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
377
378 class Vptr : public CodeBlob::Vptr {
379 };
380 };
381
382 class WhiteBox;
383 //----------------------------------------------------------------------------------------------------
384 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
385
386 class BufferBlob: public RuntimeBlob {
387 friend class VMStructs;
388 friend class AdapterBlob;
389 friend class VtableBlob;
390 friend class MethodHandlesAdapterBlob;
391 friend class UpcallStub;
392 friend class WhiteBox;
393
394 private:
395 // Creation support
396 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
397 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
398
399 void* operator new(size_t s, unsigned size) throw();
400
401 public:
402 // Creation
403 static BufferBlob* create(const char* name, uint buffer_size);
404 static BufferBlob* create(const char* name, CodeBuffer* cb);
405
406 static void free(BufferBlob* buf);
407
408 void print_on_impl(outputStream* st) const;
409 void print_value_on_impl(outputStream* st) const;
410
411 class Vptr : public RuntimeBlob::Vptr {
412 void print_on(const CodeBlob* instance, outputStream* st) const override {
413 instance->as_buffer_blob(false)->print_on_impl(st);
414 }
415 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
416 instance->as_buffer_blob(false)->print_value_on_impl(st);
417 }
418 };
419
420 static const Vptr _vpntr;
421 };
422
423
424 //----------------------------------------------------------------------------------------------------
425 // AdapterBlob: used to hold C2I/I2C adapters
426
427 class AdapterBlob: public BufferBlob {
428 public:
429 enum Entry {
430 I2C,
431 C2I,
432 C2I_Unverified,
433 C2I_No_Clinit_Check,
434 ENTRY_COUNT
435 };
436 private:
437 AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
438 // _i2c_offset is always 0 so no need to store it
439 int _c2i_offset;
440 int _c2i_unverified_offset;
441 int _c2i_no_clinit_check_offset;
442 public:
443 // Creation
444 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
445 address i2c_entry() { return code_begin(); }
446 address c2i_entry() { return i2c_entry() + _c2i_offset; }
447 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; }
448 address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; }
449 };
450
451 //---------------------------------------------------------------------------------------------------
452 class VtableBlob: public BufferBlob {
453 private:
454 VtableBlob(const char*, int);
455
456 void* operator new(size_t s, unsigned size) throw();
457
458 public:
459 // Creation
460 static VtableBlob* create(const char* name, int buffer_size);
461 };
462
463 //----------------------------------------------------------------------------------------------------
464 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
465
466 class MethodHandlesAdapterBlob: public BufferBlob {
467 private:
468 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
469
470 public:
471 // Creation
472 static MethodHandlesAdapterBlob* create(int buffer_size);
473 };
474
475
476 //----------------------------------------------------------------------------------------------------
477 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
478
479 class RuntimeStub: public RuntimeBlob {
480 friend class VMStructs;
481 private:
482 // Creation support
483 RuntimeStub(
484 const char* name,
485 CodeBuffer* cb,
486 int size,
487 int16_t frame_complete,
488 int frame_size,
489 OopMapSet* oop_maps,
490 bool caller_must_gc_arguments
491 );
492
493 void* operator new(size_t s, unsigned size) throw();
494
|
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 NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
49 All = 3, // All types (No code cache segmentation)
50 NumTypes = 4 // Number of CodeBlobTypes
51 };
52
53 // CodeBlob - superclass for all entries in the CodeCache.
54 //
55 // Subtypes are:
56 // nmethod : JIT Compiled Java methods
57 // RuntimeBlob : Non-compiled method code; generated glue code
58 // BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc.
59 // AdapterBlob : Used to hold C2I/I2C adapters
60 // VtableBlob : Used for holding vtable chunks
61 // MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
62 // BufferedInlineTypeBlob : used for pack/unpack handlers
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 BufferedInlineType,
89 RuntimeStub,
90 Deoptimization,
91 Safepoint,
92 #ifdef COMPILER2
93 Exception,
94 UncommonTrap,
95 #endif
96 Upcall,
97 Number_Of_Kinds
98 };
99
100 class UpcallStub; // for as_upcall_stub()
101 class RuntimeStub; // for as_runtime_stub()
102 class JavaFrameAnchor; // for UpcallStub::jfa_for_frame
103 class BufferBlob;
104 class AdapterBlob;
105 class SingletonBlob;
106 class ExceptionBlob;
107 class DeoptimizationBlob;
108 class SafepointBlob;
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(), "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; }
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
|