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