1 /* 2 * Copyright (c) 1998, 2024, 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/javaFrameAnchor.hpp" 32 #include "runtime/frame.hpp" 33 #include "runtime/handles.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 // 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 // ExceptionBlob : Used for stack unrolling 65 // SafepointBlob : Used to handle illegal instruction exceptions 66 // UncommonTrapBlob : Used to handle uncommon traps 67 // UpcallStub : Used for upcalls from native code 68 // 69 // 70 // Layout : continuous in the CodeCache 71 // - header 72 // - relocation 73 // - content space 74 // - instruction space 75 // - data space 76 77 enum class CodeBlobKind : u1 { 78 None, 79 Nmethod, 80 Buffer, 81 Adapter, 82 Vtable, 83 MH_Adapter, 84 Runtime_Stub, 85 Deoptimization, 86 Exception, 87 Safepoint, 88 Uncommon_Trap, 89 Upcall, 90 Number_Of_Kinds 91 }; 92 93 class UpcallStub; // for as_upcall_stub() 94 class RuntimeStub; // for as_runtime_stub() 95 class JavaFrameAnchor; // for UpcallStub::jfa_for_frame 96 97 class CodeBlob { 98 friend class VMStructs; 99 friend class JVMCIVMStructs; 100 friend class CodeCacheDumper; 101 102 protected: 103 // order fields from large to small to minimize padding between fields 104 ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob 105 const char* _name; 106 107 int _size; // total size of CodeBlob in bytes 108 int _relocation_size; // size of relocation (could be bigger than 64Kb) 109 int _content_offset; // offset to where content region begins (this includes consts, insts, stubs) 110 int _code_offset; // offset to where instructions region begins (this includes insts, stubs) 111 112 int _data_offset; // offset to where data region begins 113 int _frame_size; // size of stack frame in words (NOT slots. On x64 these are 64bit words) 114 115 S390_ONLY(int _ctable_offset;) 116 117 uint16_t _header_size; // size of header (depends on subclass) 118 int16_t _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have 119 // not finished setting up their frame. Beware of pc's in 120 // that range. There is a similar range(s) on returns 121 // which we don't detect. 122 123 CodeBlobKind _kind; // Kind of this code blob 124 125 bool _caller_must_gc_arguments; 126 127 #ifndef PRODUCT 128 AsmRemarks _asm_remarks; 129 DbgStrings _dbg_strings; 130 #endif 131 132 CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, 133 int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments); 134 135 // Simple CodeBlob used for simple BufferBlob. 136 CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size); 137 138 void operator delete(void* p) { } 139 140 public: 141 142 virtual ~CodeBlob() { 143 assert(_oop_maps == nullptr, "Not flushed"); 144 } 145 146 // Returns the space needed for CodeBlob 147 static unsigned int allocation_size(CodeBuffer* cb, int header_size); 148 static unsigned int align_code_offset(int offset); 149 150 // Deletion 151 void purge(); 152 153 // Typing 154 bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; } 155 bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; } 156 bool is_runtime_stub() const { return _kind == CodeBlobKind::Runtime_Stub; } 157 bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; } 158 bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::Uncommon_Trap; } 159 bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; } 160 bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; } 161 bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; } 162 bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; } 163 bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MH_Adapter; } 164 bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; } 165 166 // Casting 167 nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : nullptr; } 168 nmethod* as_nmethod() { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; } 169 CodeBlob* as_codeblob_or_null() const { return (CodeBlob*) this; } 170 UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; } 171 RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; } 172 173 // Boundaries 174 address header_begin() const { return (address) this; } 175 address header_end() const { return ((address) this) + _header_size; } 176 relocInfo* relocation_begin() const { return (relocInfo*) header_end(); } 177 relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); } 178 address content_begin() const { return (address) header_begin() + _content_offset; } 179 address content_end() const { return (address) header_begin() + _data_offset; } 180 address code_begin() const { return (address) header_begin() + _code_offset; } 181 // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor 182 address code_end() const { return (address) header_begin() + _data_offset; } 183 address data_begin() const { return (address) header_begin() + _data_offset; } 184 address data_end() const { return (address) header_begin() + _size; } 185 186 // Offsets 187 int content_offset() const { return _content_offset; } 188 int code_offset() const { return _code_offset; } 189 int data_offset() const { return _data_offset; } 190 191 // This field holds the beginning of the const section in the old code buffer. 192 // It is needed to fix relocations of pc-relative loads when resizing the 193 // the constant pool or moving it. 194 S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; }) 195 void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) } 196 197 // Sizes 198 int size() const { return _size; } 199 int header_size() const { return _header_size; } 200 int relocation_size() const { return pointer_delta_as_int((address) relocation_end(), (address) relocation_begin()); } 201 int content_size() const { return pointer_delta_as_int(content_end(), content_begin()); } 202 int code_size() const { return pointer_delta_as_int(code_end(), code_begin()); } 203 204 // Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed 205 void adjust_size(size_t used) { 206 _size = (int)used; 207 _data_offset = (int)used; 208 } 209 210 // Containment 211 bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); } 212 bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); } 213 bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); } 214 bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe && 215 code_contains(addr) && addr >= code_begin() + _frame_complete_offset; } 216 int frame_complete_offset() const { return _frame_complete_offset; } 217 218 // OopMap for frame 219 ImmutableOopMapSet* oop_maps() const { return _oop_maps; } 220 void set_oop_maps(OopMapSet* p); 221 222 const ImmutableOopMap* oop_map_for_slot(int slot, address return_address) const; 223 const ImmutableOopMap* oop_map_for_return_address(address return_address) const; 224 225 // Frame support. Sizes are in word units. 226 int frame_size() const { return _frame_size; } 227 void set_frame_size(int size) { _frame_size = size; } 228 229 // Returns true, if the next frame is responsible for GC'ing oops passed as arguments 230 bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; } 231 232 // Naming 233 const char* name() const { return _name; } 234 void set_name(const char* name) { _name = name; } 235 236 // Debugging 237 virtual void verify() = 0; 238 virtual void print() const; 239 virtual void print_on(outputStream* st) const; 240 virtual void print_value_on(outputStream* st) const; 241 void dump_for_addr(address addr, outputStream* st, bool verbose) const; 242 void print_code_on(outputStream* st); 243 244 // Print to stream, any comments associated with offset. 245 virtual void print_block_comment(outputStream* stream, address block_begin) const { 246 #ifndef PRODUCT 247 ptrdiff_t offset = block_begin - code_begin(); 248 assert(offset >= 0, "Expecting non-negative offset!"); 249 _asm_remarks.print(uint(offset), stream); 250 #endif 251 } 252 253 #ifndef PRODUCT 254 AsmRemarks &asm_remarks() { return _asm_remarks; } 255 DbgStrings &dbg_strings() { return _dbg_strings; } 256 257 void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); } 258 void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); } 259 #endif 260 }; 261 262 //---------------------------------------------------------------------------------------------------- 263 // RuntimeBlob: used for non-compiled method code (adapters, stubs, blobs) 264 265 class RuntimeBlob : public CodeBlob { 266 friend class VMStructs; 267 public: 268 269 // Creation 270 // a) simple CodeBlob 271 RuntimeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size) 272 : CodeBlob(name, kind, size, header_size) 273 {} 274 275 // b) full CodeBlob 276 // frame_complete is the offset from the beginning of the instructions 277 // to where the frame setup (from stackwalk viewpoint) is complete. 278 RuntimeBlob( 279 const char* name, 280 CodeBlobKind kind, 281 CodeBuffer* cb, 282 int size, 283 uint16_t header_size, 284 int16_t frame_complete, 285 int frame_size, 286 OopMapSet* oop_maps, 287 bool caller_must_gc_arguments = false 288 ); 289 290 static void free(RuntimeBlob* blob); 291 292 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService. 293 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = ""); 294 }; 295 296 class WhiteBox; 297 //---------------------------------------------------------------------------------------------------- 298 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc. 299 300 class BufferBlob: public RuntimeBlob { 301 friend class VMStructs; 302 friend class AdapterBlob; 303 friend class VtableBlob; 304 friend class MethodHandlesAdapterBlob; 305 friend class UpcallStub; 306 friend class WhiteBox; 307 308 private: 309 // Creation support 310 BufferBlob(const char* name, CodeBlobKind kind, int size); 311 BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size); 312 313 void* operator new(size_t s, unsigned size) throw(); 314 315 public: 316 // Creation 317 static BufferBlob* create(const char* name, uint buffer_size); 318 static BufferBlob* create(const char* name, CodeBuffer* cb); 319 320 static void free(BufferBlob* buf); 321 322 // Verification support 323 void verify() override; 324 325 void print_on(outputStream* st) const override; 326 void print_value_on(outputStream* st) const override; 327 }; 328 329 330 //---------------------------------------------------------------------------------------------------- 331 // AdapterBlob: used to hold C2I/I2C adapters 332 333 class AdapterBlob: public BufferBlob { 334 private: 335 AdapterBlob(int size, CodeBuffer* cb); 336 337 public: 338 // Creation 339 static AdapterBlob* create(CodeBuffer* cb); 340 }; 341 342 //--------------------------------------------------------------------------------------------------- 343 class VtableBlob: public BufferBlob { 344 private: 345 VtableBlob(const char*, int); 346 347 void* operator new(size_t s, unsigned size) throw(); 348 349 public: 350 // Creation 351 static VtableBlob* create(const char* name, int buffer_size); 352 }; 353 354 //---------------------------------------------------------------------------------------------------- 355 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters 356 357 class MethodHandlesAdapterBlob: public BufferBlob { 358 private: 359 MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MH_Adapter, size) {} 360 361 public: 362 // Creation 363 static MethodHandlesAdapterBlob* create(int buffer_size); 364 }; 365 366 367 //---------------------------------------------------------------------------------------------------- 368 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine 369 370 class RuntimeStub: public RuntimeBlob { 371 friend class VMStructs; 372 private: 373 // Creation support 374 RuntimeStub( 375 const char* name, 376 CodeBuffer* cb, 377 int size, 378 int16_t frame_complete, 379 int frame_size, 380 OopMapSet* oop_maps, 381 bool caller_must_gc_arguments 382 ); 383 384 void* operator new(size_t s, unsigned size) throw(); 385 386 public: 387 // Creation 388 static RuntimeStub* new_runtime_stub( 389 const char* stub_name, 390 CodeBuffer* cb, 391 int16_t frame_complete, 392 int frame_size, 393 OopMapSet* oop_maps, 394 bool caller_must_gc_arguments, 395 bool alloc_fail_is_fatal=true 396 ); 397 398 static void free(RuntimeStub* stub) { RuntimeBlob::free(stub); } 399 400 address entry_point() const { return code_begin(); } 401 402 // Verification support 403 void verify() override; 404 405 void print_on(outputStream* st) const override; 406 void print_value_on(outputStream* st) const override; 407 }; 408 409 410 //---------------------------------------------------------------------------------------------------- 411 // Super-class for all blobs that exist in only one instance. Implements default behaviour. 412 413 class SingletonBlob: public RuntimeBlob { 414 friend class VMStructs; 415 416 protected: 417 void* operator new(size_t s, unsigned size) throw(); 418 419 public: 420 SingletonBlob( 421 const char* name, 422 CodeBlobKind kind, 423 CodeBuffer* cb, 424 int size, 425 uint16_t header_size, 426 int frame_size, 427 OopMapSet* oop_maps 428 ) 429 : RuntimeBlob(name, kind, cb, size, header_size, CodeOffsets::frame_never_safe, frame_size, oop_maps) 430 {}; 431 432 address entry_point() { return code_begin(); } 433 434 // Verification support 435 void verify() override; // does nothing 436 437 void print_on(outputStream* st) const override; 438 void print_value_on(outputStream* st) const override; 439 }; 440 441 442 //---------------------------------------------------------------------------------------------------- 443 // DeoptimizationBlob 444 445 class DeoptimizationBlob: public SingletonBlob { 446 friend class VMStructs; 447 friend class JVMCIVMStructs; 448 private: 449 int _unpack_offset; 450 int _unpack_with_exception; 451 int _unpack_with_reexecution; 452 453 int _unpack_with_exception_in_tls; 454 455 #if INCLUDE_JVMCI 456 // Offsets when JVMCI calls uncommon_trap. 457 int _uncommon_trap_offset; 458 int _implicit_exception_uncommon_trap_offset; 459 #endif 460 461 // Creation support 462 DeoptimizationBlob( 463 CodeBuffer* cb, 464 int size, 465 OopMapSet* oop_maps, 466 int unpack_offset, 467 int unpack_with_exception_offset, 468 int unpack_with_reexecution_offset, 469 int frame_size 470 ); 471 472 public: 473 // Creation 474 static DeoptimizationBlob* create( 475 CodeBuffer* cb, 476 OopMapSet* oop_maps, 477 int unpack_offset, 478 int unpack_with_exception_offset, 479 int unpack_with_reexecution_offset, 480 int frame_size 481 ); 482 483 // Printing 484 void print_value_on(outputStream* st) const override; 485 486 address unpack() const { return code_begin() + _unpack_offset; } 487 address unpack_with_exception() const { return code_begin() + _unpack_with_exception; } 488 address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; } 489 490 // Alternate entry point for C1 where the exception and issuing pc 491 // are in JavaThread::_exception_oop and JavaThread::_exception_pc 492 // instead of being in registers. This is needed because C1 doesn't 493 // model exception paths in a way that keeps these registers free so 494 // there may be live values in those registers during deopt. 495 void set_unpack_with_exception_in_tls_offset(int offset) { 496 _unpack_with_exception_in_tls = offset; 497 assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob"); 498 } 499 address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; } 500 501 #if INCLUDE_JVMCI 502 // Offsets when JVMCI calls uncommon_trap. 503 void set_uncommon_trap_offset(int offset) { 504 _uncommon_trap_offset = offset; 505 assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob"); 506 } 507 address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; } 508 509 void set_implicit_exception_uncommon_trap_offset(int offset) { 510 _implicit_exception_uncommon_trap_offset = offset; 511 assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob"); 512 } 513 address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; } 514 #endif // INCLUDE_JVMCI 515 }; 516 517 518 //---------------------------------------------------------------------------------------------------- 519 // UncommonTrapBlob (currently only used by Compiler 2) 520 521 #ifdef COMPILER2 522 523 class UncommonTrapBlob: public SingletonBlob { 524 friend class VMStructs; 525 private: 526 // Creation support 527 UncommonTrapBlob( 528 CodeBuffer* cb, 529 int size, 530 OopMapSet* oop_maps, 531 int frame_size 532 ); 533 534 public: 535 // Creation 536 static UncommonTrapBlob* create( 537 CodeBuffer* cb, 538 OopMapSet* oop_maps, 539 int frame_size 540 ); 541 }; 542 543 544 //---------------------------------------------------------------------------------------------------- 545 // ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2) 546 547 class ExceptionBlob: public SingletonBlob { 548 friend class VMStructs; 549 private: 550 // Creation support 551 ExceptionBlob( 552 CodeBuffer* cb, 553 int size, 554 OopMapSet* oop_maps, 555 int frame_size 556 ); 557 558 public: 559 // Creation 560 static ExceptionBlob* create( 561 CodeBuffer* cb, 562 OopMapSet* oop_maps, 563 int frame_size 564 ); 565 }; 566 #endif // COMPILER2 567 568 569 //---------------------------------------------------------------------------------------------------- 570 // SafepointBlob: handles illegal_instruction exceptions during a safepoint 571 572 class SafepointBlob: public SingletonBlob { 573 friend class VMStructs; 574 private: 575 // Creation support 576 SafepointBlob( 577 CodeBuffer* cb, 578 int size, 579 OopMapSet* oop_maps, 580 int frame_size 581 ); 582 583 public: 584 // Creation 585 static SafepointBlob* create( 586 CodeBuffer* cb, 587 OopMapSet* oop_maps, 588 int frame_size 589 ); 590 }; 591 592 //---------------------------------------------------------------------------------------------------- 593 594 class UpcallLinker; 595 596 // A (Panama) upcall stub. Not used by JNI. 597 class UpcallStub: public RuntimeBlob { 598 friend class VMStructs; 599 friend class UpcallLinker; 600 private: 601 jobject _receiver; 602 ByteSize _frame_data_offset; 603 604 UpcallStub(const char* name, CodeBuffer* cb, int size, jobject receiver, ByteSize frame_data_offset); 605 606 void* operator new(size_t s, unsigned size) throw(); 607 608 struct FrameData { 609 JavaFrameAnchor jfa; 610 JavaThread* thread; 611 JNIHandleBlock* old_handles; 612 JNIHandleBlock* new_handles; 613 }; 614 615 // defined in frame_ARCH.cpp 616 FrameData* frame_data_for_frame(const frame& frame) const; 617 public: 618 // Creation 619 static UpcallStub* create(const char* name, CodeBuffer* cb, jobject receiver, ByteSize frame_data_offset); 620 621 static void free(UpcallStub* blob); 622 623 jobject receiver() { return _receiver; } 624 625 JavaFrameAnchor* jfa_for_frame(const frame& frame) const; 626 627 // GC/Verification support 628 void oops_do(OopClosure* f, const frame& frame); 629 void verify() override; 630 631 // Misc. 632 void print_on(outputStream* st) const override; 633 void print_value_on(outputStream* st) const override; 634 }; 635 636 #endif // SHARE_CODE_CODEBLOB_HPP