41
42 // CodeBlob Types
43 // Used in the CodeCache to assign CodeBlobs to different CodeHeaps
44 enum class CodeBlobType {
45 MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods)
46 MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods
47 NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
48 All = 3, // All types (No code cache segmentation)
49 NumTypes = 4 // Number of CodeBlobTypes
50 };
51
52 // CodeBlob - superclass for all entries in the CodeCache.
53 //
54 // Subtypes are:
55 // nmethod : JIT Compiled Java methods
56 // RuntimeBlob : Non-compiled method code; generated glue code
57 // BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc.
58 // AdapterBlob : Used to hold C2I/I2C adapters
59 // VtableBlob : Used for holding vtable chunks
60 // MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
61 // RuntimeStub : Call to VM runtime methods
62 // SingletonBlob : Super-class for all blobs that exist in only one instance
63 // DeoptimizationBlob : Used for deoptimization
64 // SafepointBlob : Used to handle illegal instruction exceptions
65 // ExceptionBlob : Used for stack unrolling
66 // UncommonTrapBlob : Used to handle uncommon traps
67 // UpcallStub : Used for upcalls from native code
68 //
69 //
70 // Layout in the CodeCache:
71 // - header
72 // - content space
73 // - instruction space
74 // Outside of the CodeCache:
75 // - mutable_data
76 // - relocation info
77 // - additional data for subclasses
78
79 enum class CodeBlobKind : u1 {
80 None,
81 Nmethod,
82 Buffer,
83 Adapter,
84 Vtable,
85 MHAdapter,
86 RuntimeStub,
87 Deoptimization,
88 Safepoint,
89 #ifdef COMPILER2
90 Exception,
91 UncommonTrap,
92 #endif
93 Upcall,
94 Number_Of_Kinds
95 };
96
97 class UpcallStub; // for as_upcall_stub()
98 class RuntimeStub; // for as_runtime_stub()
99 class JavaFrameAnchor; // for UpcallStub::jfa_for_frame
100 class AdapterBlob;
101 class ExceptionBlob;
102 class DeoptimizationBlob;
103 class SafepointBlob;
104 class UncommonTrapBlob;
105
184
185 // Deletion
186 void purge();
187
188 // Typing
189 bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; }
190 bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; }
191 bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
192 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
193 #ifdef COMPILER2
194 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
195 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
196 #else
197 bool is_uncommon_trap_stub() const { return false; }
198 bool is_exception_stub() const { return false; }
199 #endif
200 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
201 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
202 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
203 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
204 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
205
206 // Casting
207 nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
208 nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
209 CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
210 AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
211 ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }
212 DeoptimizationBlob* as_deoptimization_blob() const { assert(is_deoptimization_stub(), "must be deopt stub"); return (DeoptimizationBlob*) this; }
213 SafepointBlob* as_safepoint_blob() const { assert(is_safepoint_stub(), "must be safepoint stub"); return (SafepointBlob*) this; }
214 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
215 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
216 UncommonTrapBlob* as_uncommon_trap_blob() const { assert(is_uncommon_trap_stub(), "must be uncommon trap stub"); return (UncommonTrapBlob*) this; }
217
218 // Boundaries
219 address header_begin() const { return (address) this; }
220 address header_end() const { return ((address) this) + _header_size; }
221 address content_begin() const { return (address) header_begin() + _content_offset; }
222 address content_end() const { return (address) header_begin() + _data_offset; }
223 address code_begin() const { return (address) header_begin() + _code_offset; }
349 );
350
351 static void free(RuntimeBlob* blob);
352
353 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
354 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
355
356 class Vptr : public CodeBlob::Vptr {
357 };
358 };
359
360 class WhiteBox;
361 //----------------------------------------------------------------------------------------------------
362 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
363
364 class BufferBlob: public RuntimeBlob {
365 friend class VMStructs;
366 friend class AdapterBlob;
367 friend class VtableBlob;
368 friend class MethodHandlesAdapterBlob;
369 friend class UpcallStub;
370 friend class WhiteBox;
371
372 private:
373 // Creation support
374 BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
375 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
376
377 void* operator new(size_t s, unsigned size) throw();
378
379 public:
380 // Creation
381 static BufferBlob* create(const char* name, uint buffer_size);
382 static BufferBlob* create(const char* name, CodeBuffer* cb);
383
384 static void free(BufferBlob* buf);
385
386 void print_on_impl(outputStream* st) const;
387 void print_value_on_impl(outputStream* st) const;
388
389 class Vptr : public RuntimeBlob::Vptr {
390 void print_on(const CodeBlob* instance, outputStream* st) const override {
391 ((const BufferBlob*)instance)->print_on_impl(st);
392 }
393 void print_value_on(const CodeBlob* instance, outputStream* st) const override {
394 ((const BufferBlob*)instance)->print_value_on_impl(st);
395 }
396 };
397
398 static const Vptr _vpntr;
399 };
400
401
402 //----------------------------------------------------------------------------------------------------
403 // AdapterBlob: used to hold C2I/I2C adapters
404
405 class AdapterBlob: public BufferBlob {
406 public:
407 enum Entry {
408 I2C,
409 C2I,
410 C2I_Unverified,
411 C2I_No_Clinit_Check,
412 ENTRY_COUNT
413 };
414 private:
415 AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
416 // _i2c_offset is always 0 so no need to store it
417 int _c2i_offset;
418 int _c2i_unverified_offset;
419 int _c2i_no_clinit_check_offset;
420 public:
421 // Creation
422 static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
423 address i2c_entry() { return code_begin(); }
424 address c2i_entry() { return i2c_entry() + _c2i_offset; }
425 address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; }
426 address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; }
427 };
428
429 //---------------------------------------------------------------------------------------------------
430 class VtableBlob: public BufferBlob {
431 private:
432 VtableBlob(const char*, int);
433
434 void* operator new(size_t s, unsigned size) throw();
435
436 public:
437 // Creation
438 static VtableBlob* create(const char* name, int buffer_size);
439 };
440
441 //----------------------------------------------------------------------------------------------------
442 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
443
444 class MethodHandlesAdapterBlob: public BufferBlob {
445 private:
446 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
447
448 public:
449 // Creation
450 static MethodHandlesAdapterBlob* create(int buffer_size);
451 };
452
453
454 //----------------------------------------------------------------------------------------------------
455 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
456
457 class RuntimeStub: public RuntimeBlob {
458 friend class VMStructs;
459 private:
460 // Creation support
461 RuntimeStub(
462 const char* name,
463 CodeBuffer* cb,
464 int size,
465 int16_t frame_complete,
466 int frame_size,
467 OopMapSet* oop_maps,
468 bool caller_must_gc_arguments
469 );
470
471 void* operator new(size_t s, unsigned size) throw();
472
|
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
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; }
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
|