Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/vframeArray.hpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
diff
changeset
|
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
diff
changeset
|
21 * questions. |
0 | 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 | |
31 class LocalsClosure; | |
32 class ExpressionStackClosure; | |
33 class MonitorStackClosure; | |
34 class MonitorArrayElement; | |
35 class StackValueCollection; | |
36 | |
37 // A vframeArrayElement is an element of a vframeArray. Each element | |
38 // represent an interpreter frame which will eventually be created. | |
39 | |
40 class vframeArrayElement : public _ValueObj { | |
41 private: | |
42 | |
43 frame _frame; // the interpreter frame we will unpack into | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
44 int _bci; // raw bci for this vframe |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
45 bool _reexecute; // whether sould we reexecute this bytecode |
0 | 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; } | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
58 bool should_reexecute(void) const { return _reexecute; } |
0 | 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 | |
98 class 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 }; |