duke@435: /* mikael@6198: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_RUNTIME_VFRAMEARRAY_HPP stefank@2314: #define SHARE_VM_RUNTIME_VFRAMEARRAY_HPP stefank@2314: stefank@2314: #include "oops/arrayOop.hpp" stefank@2314: #include "runtime/deoptimization.hpp" stefank@2314: #include "runtime/frame.inline.hpp" stefank@2314: #include "runtime/monitorChunk.hpp" stefank@2314: #include "utilities/growableArray.hpp" stefank@2314: duke@435: // A vframeArray is an array used for momentarily storing off stack Java method activations duke@435: // during deoptimization. Essentially it is an array of vframes where each vframe duke@435: // data is stored off stack. This structure will never exist across a safepoint so duke@435: // there is no need to gc any oops that are stored in the structure. duke@435: duke@435: duke@435: class LocalsClosure; duke@435: class ExpressionStackClosure; duke@435: class MonitorStackClosure; duke@435: class MonitorArrayElement; duke@435: class StackValueCollection; duke@435: duke@435: // A vframeArrayElement is an element of a vframeArray. Each element duke@435: // represent an interpreter frame which will eventually be created. duke@435: duke@435: class vframeArrayElement : public _ValueObj { never@3138: friend class VMStructs; never@3138: duke@435: private: duke@435: duke@435: frame _frame; // the interpreter frame we will unpack into cfang@1335: int _bci; // raw bci for this vframe cfang@1335: bool _reexecute; // whether sould we reexecute this bytecode coleenp@4037: Method* _method; // the method for this vframe duke@435: MonitorChunk* _monitors; // active monitors for this vframe duke@435: StackValueCollection* _locals; duke@435: StackValueCollection* _expressions; duke@435: duke@435: public: duke@435: duke@435: frame* iframe(void) { return &_frame; } duke@435: duke@435: int bci(void) const; duke@435: duke@435: int raw_bci(void) const { return _bci; } cfang@1335: bool should_reexecute(void) const { return _reexecute; } duke@435: coleenp@4037: Method* method(void) const { return _method; } duke@435: duke@435: MonitorChunk* monitors(void) const { return _monitors; } duke@435: duke@435: void free_monitors(JavaThread* jt); duke@435: duke@435: StackValueCollection* locals(void) const { return _locals; } duke@435: duke@435: StackValueCollection* expressions(void) const { return _expressions; } duke@435: duke@435: void fill_in(compiledVFrame* vf); duke@435: duke@435: // Formerly part of deoptimizedVFrame duke@435: duke@435: duke@435: // Returns the on stack word size for this frame duke@435: // callee_parameters is the number of callee locals residing inside this frame roland@6723: int on_stack_size(int callee_parameters, duke@435: int callee_locals, duke@435: bool is_top_frame, duke@435: int popframe_extra_stack_expression_els) const; duke@435: duke@435: // Unpacks the element to skeletal interpreter frame never@2901: void unpack_on_stack(int caller_actual_parameters, never@2901: int callee_parameters, duke@435: int callee_locals, duke@435: frame* caller, duke@435: bool is_top_frame, roland@4727: bool is_bottom_frame, duke@435: int exec_mode); duke@435: duke@435: #ifndef PRODUCT duke@435: void print(outputStream* st); duke@435: #endif /* PRODUCT */ duke@435: }; duke@435: duke@435: // this can be a ResourceObj if we don't save the last one... duke@435: // but it does make debugging easier even if we can't look duke@435: // at the data in each vframeElement duke@435: zgu@3900: class vframeArray: public CHeapObj { never@3138: friend class VMStructs; never@3138: duke@435: private: duke@435: duke@435: duke@435: // Here is what a vframeArray looks like in memory duke@435: duke@435: /* duke@435: fixed part duke@435: description of the original frame duke@435: _frames - number of vframes in this array duke@435: adapter info duke@435: callee register save area duke@435: variable part duke@435: vframeArrayElement [ 0 ] duke@435: ... duke@435: vframeArrayElement [_frames - 1] duke@435: duke@435: */ duke@435: duke@435: JavaThread* _owner_thread; duke@435: vframeArray* _next; duke@435: frame _original; // the original frame of the deoptee duke@435: frame _caller; // caller of root frame in vframeArray duke@435: frame _sender; duke@435: duke@435: Deoptimization::UnrollBlock* _unroll_block; duke@435: int _frame_size; duke@435: duke@435: int _frames; // number of javavframes in the array (does not count any adapter) duke@435: duke@435: intptr_t _callee_registers[RegisterMap::reg_count]; duke@435: unsigned char _valid[RegisterMap::reg_count]; duke@435: duke@435: vframeArrayElement _elements[1]; // First variable section. duke@435: duke@435: void fill_in_element(int index, compiledVFrame* vf); duke@435: duke@435: bool is_location_valid(int i) const { return _valid[i] != 0; } duke@435: void set_location_valid(int i, bool valid) { _valid[i] = valid; } duke@435: duke@435: public: duke@435: duke@435: duke@435: // Tells whether index is within bounds. duke@435: bool is_within_bounds(int index) const { return 0 <= index && index < frames(); } duke@435: duke@435: // Accessores for instance variable duke@435: int frames() const { return _frames; } duke@435: duke@435: static vframeArray* allocate(JavaThread* thread, int frame_size, GrowableArray* chunk, duke@435: RegisterMap* reg_map, frame sender, frame caller, frame self); duke@435: duke@435: duke@435: vframeArrayElement* element(int index) { assert(is_within_bounds(index), "Bad index"); return &_elements[index]; } duke@435: duke@435: // Allocates a new vframe in the array and fills the array with vframe information in chunk duke@435: void fill_in(JavaThread* thread, int frame_size, GrowableArray* chunk, const RegisterMap *reg_map); duke@435: duke@435: // Returns the owner of this vframeArray duke@435: JavaThread* owner_thread() const { return _owner_thread; } duke@435: duke@435: // Accessors for next duke@435: vframeArray* next() const { return _next; } duke@435: void set_next(vframeArray* value) { _next = value; } duke@435: duke@435: // Accessors for sp duke@435: intptr_t* sp() const { return _original.sp(); } duke@435: duke@435: intptr_t* unextended_sp() const { return _original.unextended_sp(); } duke@435: duke@435: address original_pc() const { return _original.pc(); } duke@435: duke@435: frame original() const { return _original; } duke@435: duke@435: frame caller() const { return _caller; } duke@435: duke@435: frame sender() const { return _sender; } duke@435: duke@435: // Accessors for unroll block duke@435: Deoptimization::UnrollBlock* unroll_block() const { return _unroll_block; } duke@435: void set_unroll_block(Deoptimization::UnrollBlock* block) { _unroll_block = block; } duke@435: duke@435: // Returns the size of the frame that got deoptimized duke@435: int frame_size() const { return _frame_size; } duke@435: duke@435: // Unpack the array on the stack passed in stack interval never@2901: void unpack_to_stack(frame &unpack_frame, int exec_mode, int caller_actual_parameters); duke@435: duke@435: // Deallocates monitor chunks allocated during deoptimization. duke@435: // This should be called when the array is not used anymore. duke@435: void deallocate_monitor_chunks(); duke@435: duke@435: duke@435: duke@435: // Accessor for register map duke@435: address register_location(int i) const; duke@435: duke@435: void print_on_2(outputStream* st) PRODUCT_RETURN; duke@435: void print_value_on(outputStream* st) const PRODUCT_RETURN; duke@435: duke@435: #ifndef PRODUCT duke@435: // Comparing duke@435: bool structural_compare(JavaThread* thread, GrowableArray* chunk); duke@435: #endif duke@435: duke@435: }; stefank@2314: stefank@2314: #endif // SHARE_VM_RUNTIME_VFRAMEARRAY_HPP