1 /* 2 * Copyright (c) 1997, 2019, 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_RUNTIME_VFRAMEARRAY_HPP 26 #define SHARE_RUNTIME_VFRAMEARRAY_HPP 27 28 #include "memory/allocation.hpp" 29 #include "oops/arrayOop.hpp" 30 #include "runtime/deoptimization.hpp" 31 #include "runtime/frame.hpp" 32 #include "runtime/monitorChunk.hpp" 33 #include "utilities/growableArray.hpp" 34 35 // A vframeArray is an array used for momentarily storing off stack Java method activations 36 // during deoptimization. Essentially it is an array of vframes where each vframe 37 // data is stored off stack. This structure will never exist across a safepoint so 38 // there is no need to gc any oops that are stored in the structure. 39 40 41 class LocalsClosure; 42 class ExpressionStackClosure; 43 class MonitorStackClosure; 44 class MonitorArrayElement; 45 class StackValueCollection; 46 47 // A vframeArrayElement is an element of a vframeArray. Each element 48 // represent an interpreter frame which will eventually be created. 49 50 class vframeArrayElement { 51 friend class VMStructs; 52 53 private: 54 55 frame _frame; // the interpreter frame we will unpack into 56 int _bci; // raw bci for this vframe 57 bool _reexecute; // whether we should reexecute this bytecode 58 Method* _method; // the method for this vframe 59 MonitorChunk* _monitors; // active monitors for this vframe 60 StackValueCollection* _locals; 61 StackValueCollection* _expressions; 62 #ifdef ASSERT 63 bool _removed_monitors; 64 #endif 65 66 public: 67 iframe(void)68 frame* iframe(void) { return &_frame; } 69 70 int bci(void) const; 71 raw_bci(void) const72 int raw_bci(void) const { return _bci; } should_reexecute(void) const73 bool should_reexecute(void) const { return _reexecute; } 74 method(void) const75 Method* method(void) const { return _method; } 76 monitors(void) const77 MonitorChunk* monitors(void) const { return _monitors; } 78 79 void free_monitors(JavaThread* jt); 80 locals(void) const81 StackValueCollection* locals(void) const { return _locals; } 82 expressions(void) const83 StackValueCollection* expressions(void) const { return _expressions; } 84 85 void fill_in(compiledVFrame* vf, bool realloc_failures); 86 87 // Formerly part of deoptimizedVFrame 88 89 90 // Returns the on stack word size for this frame 91 // callee_parameters is the number of callee locals residing inside this frame 92 int on_stack_size(int callee_parameters, 93 int callee_locals, 94 bool is_top_frame, 95 int popframe_extra_stack_expression_els) const; 96 97 // Unpacks the element to skeletal interpreter frame 98 void unpack_on_stack(int caller_actual_parameters, 99 int callee_parameters, 100 int callee_locals, 101 frame* caller, 102 bool is_top_frame, 103 bool is_bottom_frame, 104 int exec_mode); 105 106 #ifdef ASSERT set_removed_monitors()107 void set_removed_monitors() { 108 _removed_monitors = true; 109 } 110 #endif 111 112 #ifndef PRODUCT 113 void print(outputStream* st); 114 #endif /* PRODUCT */ 115 }; 116 117 // this can be a ResourceObj if we don't save the last one... 118 // but it does make debugging easier even if we can't look 119 // at the data in each vframeElement 120 121 class vframeArray: public CHeapObj<mtCompiler> { 122 friend class VMStructs; 123 124 private: 125 126 127 // Here is what a vframeArray looks like in memory 128 129 /* 130 fixed part 131 description of the original frame 132 _frames - number of vframes in this array 133 adapter info 134 callee register save area 135 variable part 136 vframeArrayElement [ 0 ] 137 ... 138 vframeArrayElement [_frames - 1] 139 140 */ 141 142 JavaThread* _owner_thread; 143 vframeArray* _next; 144 frame _original; // the original frame of the deoptee 145 frame _caller; // caller of root frame in vframeArray 146 frame _sender; 147 148 Deoptimization::UnrollBlock* _unroll_block; 149 int _frame_size; 150 151 int _frames; // number of javavframes in the array (does not count any adapter) 152 153 intptr_t _callee_registers[RegisterMap::reg_count]; 154 unsigned char _valid[RegisterMap::reg_count]; 155 156 vframeArrayElement _elements[1]; // First variable section. 157 158 void fill_in_element(int index, compiledVFrame* vf); 159 is_location_valid(int i) const160 bool is_location_valid(int i) const { return _valid[i] != 0; } set_location_valid(int i,bool valid)161 void set_location_valid(int i, bool valid) { _valid[i] = valid; } 162 163 public: 164 165 166 // Tells whether index is within bounds. is_within_bounds(int index) const167 bool is_within_bounds(int index) const { return 0 <= index && index < frames(); } 168 169 // Accessories for instance variable frames() const170 int frames() const { return _frames; } 171 172 static vframeArray* allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, 173 RegisterMap* reg_map, frame sender, frame caller, frame self, 174 bool realloc_failures); 175 176 element(int index)177 vframeArrayElement* element(int index) { assert(is_within_bounds(index), "Bad index"); return &_elements[index]; } 178 179 // Allocates a new vframe in the array and fills the array with vframe information in chunk 180 void fill_in(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, const RegisterMap *reg_map, bool realloc_failures); 181 182 // Returns the owner of this vframeArray owner_thread() const183 JavaThread* owner_thread() const { return _owner_thread; } 184 185 // Accessors for next next() const186 vframeArray* next() const { return _next; } set_next(vframeArray * value)187 void set_next(vframeArray* value) { _next = value; } 188 189 // Accessors for sp sp() const190 intptr_t* sp() const { return _original.sp(); } 191 192 intptr_t* unextended_sp() const; 193 original_pc() const194 address original_pc() const { return _original.pc(); } 195 original() const196 frame original() const { return _original; } 197 caller() const198 frame caller() const { return _caller; } 199 sender() const200 frame sender() const { return _sender; } 201 202 // Accessors for unroll block unroll_block() const203 Deoptimization::UnrollBlock* unroll_block() const { return _unroll_block; } set_unroll_block(Deoptimization::UnrollBlock * block)204 void set_unroll_block(Deoptimization::UnrollBlock* block) { _unroll_block = block; } 205 206 // Returns the size of the frame that got deoptimized frame_size() const207 int frame_size() const { return _frame_size; } 208 209 // Unpack the array on the stack passed in stack interval 210 void unpack_to_stack(frame &unpack_frame, int exec_mode, int caller_actual_parameters); 211 212 // Deallocates monitor chunks allocated during deoptimization. 213 // This should be called when the array is not used anymore. 214 void deallocate_monitor_chunks(); 215 216 217 218 // Accessor for register map 219 address register_location(int i) const; 220 221 void print_on_2(outputStream* st) PRODUCT_RETURN; 222 void print_value_on(outputStream* st) const PRODUCT_RETURN; 223 224 #ifndef PRODUCT 225 // Comparing 226 bool structural_compare(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk); 227 #endif 228 229 }; 230 231 #endif // SHARE_RUNTIME_VFRAMEARRAY_HPP 232