1 /* 2 * Copyright (c) 2000, 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_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/c2_CodeStubs.hpp" 33 #include "opto/constantTable.hpp" 34 #include "opto/phase.hpp" 35 #include "runtime/vm_version.hpp" 36 #include "utilities/globalDefinitions.hpp" 37 #include "utilities/macros.hpp" 38 39 class AbstractCompiler; 40 class Arena; 41 class Bundle; 42 class Block; 43 class Block_Array; 44 class C2_MacroAssembler; 45 class ciMethod; 46 class Compile; 47 class MachNode; 48 class MachSafePointNode; 49 class Node; 50 class PhaseCFG; 51 #ifndef PRODUCT 52 #define DEBUG_ARG(x) , x 53 #else 54 #define DEBUG_ARG(x) 55 #endif 56 57 class BufferSizingData { 58 public: 59 int _stub; 60 int _code; 61 int _const; 62 int _reloc; 63 64 BufferSizingData() : 65 _stub(0), 66 _code(0), 67 _const(0), 68 _reloc(0) 69 { }; 70 }; 71 72 class PhaseOutput : public Phase { 73 private: 74 // Instruction bits passed off to the VM 75 CodeBuffer _code_buffer; // Where the code is assembled 76 int _first_block_size; // Size of unvalidated entry point code / OSR poison code 77 ExceptionHandlerTable _handler_table; // Table of native-code exception handlers 78 ImplicitExceptionTable _inc_table; // Table of implicit null checks in native code 79 C2CodeStubList _stub_list; // List of code stubs 80 OopMapSet* _oop_map_set; // Table of oop maps (one for each safepoint location) 81 BufferBlob* _scratch_buffer_blob; // For temporary code buffers. 82 relocInfo* _scratch_locs_memory; // For temporary code buffers. 83 int _scratch_const_size; // For temporary code buffers. 84 bool _in_scratch_emit_size; // true when in scratch_emit_size. 85 86 int _frame_slots; // Size of total frame in stack slots 87 CodeOffsets _code_offsets; // Offsets into the code for various interesting entries 88 89 uint _node_bundling_limit; 90 Bundle* _node_bundling_base; // Information for instruction bundling 91 92 // For deopt 93 int _orig_pc_slot; 94 int _orig_pc_slot_offset_in_bytes; 95 96 ConstantTable _constant_table; // The constant table for this compilation unit. 97 98 BufferSizingData _buf_sizes; 99 Block* _block; 100 uint _index; 101 102 void perform_mach_node_analysis(); 103 void pd_perform_mach_node_analysis(); 104 105 public: 106 PhaseOutput(); 107 ~PhaseOutput(); 108 109 // Convert Nodes to instruction bits and pass off to the VM 110 void Output(); 111 bool need_stack_bang(int frame_size_in_bytes) const; 112 bool need_register_stack_bang() const; 113 void compute_loop_first_inst_sizes(); 114 115 void install_code(ciMethod* target, 116 int entry_bci, 117 AbstractCompiler* compiler, 118 bool has_unsafe_access, 119 bool has_wide_vectors); 120 121 void install_stub(const char* stub_name); 122 123 // Constant table 124 ConstantTable& constant_table() { return _constant_table; } 125 126 // Code stubs list 127 void add_stub(C2CodeStub* stub) { _stub_list.add_stub(stub); } 128 129 // Code emission iterator 130 Block* block() { return _block; } 131 int index() { return _index; } 132 133 // The architecture description provides short branch variants for some long 134 // branch instructions. Replace eligible long branches with short branches. 135 void shorten_branches(uint* blk_starts); 136 // If "objs" contains an ObjectValue whose id is "id", returns it, else null. 137 static ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id); 138 static void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, ObjectValue* sv); 139 void FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, 140 GrowableArray<ScopeValue*> *array, 141 GrowableArray<ScopeValue*> *objs ); 142 143 void Process_OopMap_Node(MachNode *mach, int current_offset); 144 145 // Initialize code buffer 146 void estimate_buffer_size(int& const_req); 147 CodeBuffer* init_buffer(); 148 149 // Write out basic block data to code buffer 150 void fill_buffer(C2_MacroAssembler* masm, uint* blk_starts); 151 152 // Compute the information for the exception tables 153 void FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels); 154 155 // Perform instruction scheduling and bundling over the sequence of 156 // instructions in backwards order. 157 void ScheduleAndBundle(); 158 159 void install(); 160 161 // Instruction bits passed off to the VM 162 CodeBuffer* code_buffer() { return &_code_buffer; } 163 int first_block_size() { return _first_block_size; } 164 void set_frame_complete(int off) { if (!in_scratch_emit_size()) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); } } 165 ExceptionHandlerTable* handler_table() { return &_handler_table; } 166 ImplicitExceptionTable* inc_table() { return &_inc_table; } 167 OopMapSet* oop_map_set() { return _oop_map_set; } 168 169 // Scratch buffer 170 BufferBlob* scratch_buffer_blob() { return _scratch_buffer_blob; } 171 void init_scratch_buffer_blob(int const_size); 172 void clear_scratch_buffer_blob(); 173 void set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; } 174 relocInfo* scratch_locs_memory() { return _scratch_locs_memory; } 175 void set_scratch_locs_memory(relocInfo* b) { _scratch_locs_memory = b; } 176 int scratch_buffer_code_size() { return (address)scratch_locs_memory() - _scratch_buffer_blob->content_begin(); } 177 178 // emit to scratch blob, report resulting size 179 uint scratch_emit_size(const Node* n); 180 void set_in_scratch_emit_size(bool x) { _in_scratch_emit_size = x; } 181 bool in_scratch_emit_size() const { return _in_scratch_emit_size; } 182 183 BufferSizingData* buffer_sizing_data() { return &_buf_sizes; } 184 185 // SCCache::write_nmethod bails when nmethod buffer is expanded. 186 // Large methods would routinely expand the buffer, making themselves 187 // ineligible for SCCache stores. In order to minimize this effect, 188 // we default to larger default sizes. We do this only when SCC dumping 189 // is active, to avoid impact on default configuration. 190 // 191 // Additionally, GC barrier stubs expand up to MAX_inst_size in mainline, 192 // which also forced resizes often. Current code replaces it with 193 // max_inst_gcstub_size, which equals to old MAX_inst_size, so GC stubs 194 // still fit nicely, and do not force the resizes too often. 195 // 196 // The old enum is renamed, so direct misuse in new code from mainline would 197 // be caught as build failure. 198 // 199 // TODO: Revert this back to mainline once SCCache is fixed. 200 enum ScratchBufferBlob { 201 mainline_MAX_inst_size = 2048, 202 MAX_locs_size = 128, // number of relocInfo elements 203 MAX_const_size = 128, 204 MAX_stubs_size = 128 205 }; 206 207 // Current uses of MAX_inst_size should be replaced with these getters: 208 static int max_inst_size(); 209 static int max_inst_gcstub_size(); 210 211 int frame_slots() const { return _frame_slots; } 212 int frame_size_in_words() const; // frame_slots in units of the polymorphic 'words' 213 int frame_size_in_bytes() const { return _frame_slots << LogBytesPerInt; } 214 215 int bang_size_in_bytes() const; 216 217 void set_node_bundling_limit(uint n) { _node_bundling_limit = n; } 218 void set_node_bundling_base(Bundle* b) { _node_bundling_base = b; } 219 220 Bundle* node_bundling(const Node *n); 221 bool valid_bundle_info(const Node *n); 222 223 bool starts_bundle(const Node *n) const; 224 bool contains_as_owner(GrowableArray<MonitorValue*> *monarray, ObjectValue *ov) const; 225 bool contains_as_scalarized_obj(JVMState* jvms, MachSafePointNode* sfn, 226 GrowableArray<ScopeValue*>* objs, 227 ObjectValue* ov) const; 228 229 // Dump formatted assembly 230 #if defined(SUPPORT_OPTO_ASSEMBLY) 231 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit); 232 #else 233 void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit) { return; } 234 #endif 235 236 // Build OopMaps for each GC point 237 void BuildOopMaps(); 238 239 #ifndef PRODUCT 240 void print_scheduling(outputStream* output_stream); 241 void print_scheduling(); // to tty for debugging 242 static void print_statistics(); 243 #endif 244 }; 245 246 #endif // SHARE_OPTO_OUTPUT_HPP