1 /* 2 * Copyright (c) 2000, 2023, 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_OPTO_OUTPUT_HPP 26 #define SHARE_OPTO_OUTPUT_HPP 27 28 #include "code/debugInfo.hpp" 29 #include "code/exceptionHandlerTable.hpp" 30 #include "metaprogramming/enableIf.hpp" 31 #include "opto/ad.hpp" 32 #include "opto/constantTable.hpp" 33 #include "opto/phase.hpp" 34 #include "runtime/vm_version.hpp" 35 #include "utilities/globalDefinitions.hpp" 36 #include "utilities/macros.hpp" 37 38 class AbstractCompiler; 39 class Arena; 40 class Bundle; 41 class Block; 42 class Block_Array; 43 class ciMethod; 44 class Compile; 45 class MachNode; 46 class MachSafePointNode; 47 class Node; 48 class PhaseCFG; 49 #ifndef PRODUCT 50 #define DEBUG_ARG(x) , x 51 #else 52 #define DEBUG_ARG(x) 53 #endif 54 55 // Define the initial sizes for allocation of the resizable code buffer 56 enum { 57 initial_const_capacity = 4 * 1024 58 }; 59 60 class BufferSizingData { 61 public: 62 int _stub; 63 int _code; 64 int _const; 65 int _reloc; 66 67 BufferSizingData() : 68 _stub(0), 69 _code(0), 70 _const(0), 71 _reloc(0) 72 { }; 73 }; 74 75 class C2SafepointPollStubTable { 76 private: 77 struct C2SafepointPollStub: public ResourceObj { 78 uintptr_t _safepoint_offset; 79 Label _stub_label; 80 Label _trampoline_label; 81 C2SafepointPollStub(uintptr_t safepoint_offset) : 82 _safepoint_offset(safepoint_offset), 83 _stub_label(), 84 _trampoline_label() {} 85 }; 86 87 GrowableArray<C2SafepointPollStub*> _safepoints; 88 89 static volatile int _stub_size; 90 91 void emit_stub_impl(MacroAssembler& masm, C2SafepointPollStub* entry) const; 92 93 // The selection logic below relieves the need to add dummy files to unsupported platforms. 94 template <bool enabled> 95 typename EnableIf<enabled>::type 96 select_emit_stub(MacroAssembler& masm, C2SafepointPollStub* entry) const { 97 emit_stub_impl(masm, entry); 98 } 99 100 template <bool enabled> 101 typename EnableIf<!enabled>::type 102 select_emit_stub(MacroAssembler& masm, C2SafepointPollStub* entry) const {} 103 104 void emit_stub(MacroAssembler& masm, C2SafepointPollStub* entry) const { 105 select_emit_stub<VM_Version::supports_stack_watermark_barrier()>(masm, entry); 106 } 107 108 int stub_size_lazy() const; 109 110 public: 111 Label& add_safepoint(uintptr_t safepoint_offset); 112 int estimate_stub_size() const; 113 void emit(CodeBuffer& cb); 114 }; 115 116 class PhaseOutput : public Phase { 117 private: 118 // Instruction bits passed off to the VM 119 int _method_size; // Size of nmethod code segment in bytes 120 CodeBuffer _code_buffer; // Where the code is assembled 121 int _first_block_size; // Size of unvalidated entry point code / OSR poison code 122 ExceptionHandlerTable _handler_table; // Table of native-code exception handlers 123 ImplicitExceptionTable _inc_table; // Table of implicit null checks in native code 124 C2SafepointPollStubTable _safepoint_poll_table;// Table for safepoint polls 125 OopMapSet* _oop_map_set; // Table of oop maps (one for each safepoint location) 126 BufferBlob* _scratch_buffer_blob; // For temporary code buffers. 127 relocInfo* _scratch_locs_memory; // For temporary code buffers. 128 int _scratch_const_size; // For temporary code buffers. 129 bool _in_scratch_emit_size; // true when in scratch_emit_size. 130 131 int _frame_slots; // Size of total frame in stack slots 132 CodeOffsets _code_offsets; // Offsets into the code for various interesting entries 133 134 uint _node_bundling_limit; 135 Bundle* _node_bundling_base; // Information for instruction bundling 136 137 // For deopt 138 int _orig_pc_slot; 139 int _orig_pc_slot_offset_in_bytes; 140 141 ConstantTable _constant_table; // The constant table for this compilation unit. 142 143 BufferSizingData _buf_sizes; 144 Block* _block; 145 uint _index; 146 147 void perform_mach_node_analysis(); 148 void pd_perform_mach_node_analysis(); 149 150 public: 151 PhaseOutput(); 152 ~PhaseOutput(); 153 154 // Convert Nodes to instruction bits and pass off to the VM 155 void Output(); 156 bool need_stack_bang(int frame_size_in_bytes) const; 157 bool need_register_stack_bang() const; 158 void compute_loop_first_inst_sizes(); 159 160 void install_code(ciMethod* target, 161 int entry_bci, 162 AbstractCompiler* compiler, 163 bool has_unsafe_access, 164 bool has_wide_vectors, 165 RTMState rtm_state); 166 167 void install_stub(const char* stub_name); 168 169 // Constant table 170 ConstantTable& constant_table() { return _constant_table; } 171 172 // Safepoint poll table 173 C2SafepointPollStubTable* safepoint_poll_table() { return &_safepoint_poll_table; } 174 175 // Code emission iterator 176 Block* block() { return _block; } 177 int index() { return _index; } 178 179 // The architecture description provides short branch variants for some long 180 // branch instructions. Replace eligible long branches with short branches. 181 void shorten_branches(uint* blk_starts); 182 // If "objs" contains an ObjectValue whose id is "id", returns it, else null. 183 static ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id); 184 static void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, ObjectValue* sv); 185 void FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, 186 GrowableArray<ScopeValue*> *array, 187 GrowableArray<ScopeValue*> *objs ); 188 189 void Process_OopMap_Node(MachNode *mach, int current_offset); 190 191 // Initialize code buffer 192 void estimate_buffer_size(int& const_req); 193 CodeBuffer* init_buffer(); 194 195 // Write out basic block data to code buffer 196 void fill_buffer(CodeBuffer* cb, uint* blk_starts); 197 198 // Compute the information for the exception tables 199 void FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels); 200 201 // Perform instruction scheduling and bundling over the sequence of 202 // instructions in backwards order. 203 void ScheduleAndBundle(); 204 205 void install(); 206 207 // Instruction bits passed off to the VM 208 int code_size() { return _method_size; } 209 CodeBuffer* code_buffer() { return &_code_buffer; } 210 int first_block_size() { return _first_block_size; } 211 void set_frame_complete(int off) { if (!in_scratch_emit_size()) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); } } 212 ExceptionHandlerTable* handler_table() { return &_handler_table; } 213 ImplicitExceptionTable* inc_table() { return &_inc_table; } 214 OopMapSet* oop_map_set() { return _oop_map_set; } 215 216 // Scratch buffer 217 BufferBlob* scratch_buffer_blob() { return _scratch_buffer_blob; } 218 void init_scratch_buffer_blob(int const_size); 219 void clear_scratch_buffer_blob(); 220 void set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; } 221 relocInfo* scratch_locs_memory() { return _scratch_locs_memory; } 222 void set_scratch_locs_memory(relocInfo* b) { _scratch_locs_memory = b; } 223 int scratch_buffer_code_size() { return (address)scratch_locs_memory() - _scratch_buffer_blob->content_begin(); } 224 225 // emit to scratch blob, report resulting size 226 uint scratch_emit_size(const Node* n); 227 void set_in_scratch_emit_size(bool x) { _in_scratch_emit_size = x; } 228 bool in_scratch_emit_size() const { return _in_scratch_emit_size; } 229 230 enum ScratchBufferBlob { 231 MAX_inst_size = 2048, 232 MAX_locs_size = 128, // number of relocInfo elements 233 MAX_const_size = 128, 234 MAX_stubs_size = 128 235 }; 236 237 int frame_slots() const { return _frame_slots; } 238 int frame_size_in_words() const; // frame_slots in units of the polymorphic 'words' 239 int frame_size_in_bytes() const { return _frame_slots << LogBytesPerInt; } 240 241 int bang_size_in_bytes() const; 242 243 uint node_bundling_limit(); 244 Bundle* node_bundling_base(); 245 void set_node_bundling_limit(uint n) { _node_bundling_limit = n; } 246 void set_node_bundling_base(Bundle* b) { _node_bundling_base = b; } 247 248 Bundle* node_bundling(const Node *n); 249 bool valid_bundle_info(const Node *n); 250 251 bool starts_bundle(const Node *n) const; 252 253 // Dump formatted assembly 254 #if defined(SUPPORT_OPTO_ASSEMBLY) 255 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit); 256 void dump_asm(int* pcs = NULL, uint pc_limit = 0) { dump_asm_on(tty, pcs, pc_limit); } 257 #else 258 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit) { return; } 259 void dump_asm(int* pcs = NULL, uint pc_limit = 0) { return; } 260 #endif 261 262 // Build OopMaps for each GC point 263 void BuildOopMaps(); 264 265 #ifndef PRODUCT 266 static void print_statistics(); 267 #endif 268 }; 269 270 #endif // SHARE_OPTO_OUTPUT_HPP