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