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