45 // See comment in StackMapTable about _frame_count about why these |
47 // See comment in StackMapTable about _frame_count about why these |
46 // fields are int32_t instead of u2. |
48 // fields are int32_t instead of u2. |
47 int32_t _locals_size; // number of valid type elements in _locals |
49 int32_t _locals_size; // number of valid type elements in _locals |
48 int32_t _stack_size; // number of valid type elements in _stack |
50 int32_t _stack_size; // number of valid type elements in _stack |
49 |
51 |
|
52 int32_t _stack_mark; // Records the size of the stack prior to an |
|
53 // instruction modification, to allow rewinding |
|
54 // when/if an error occurs. |
|
55 |
50 int32_t _max_locals; |
56 int32_t _max_locals; |
51 int32_t _max_stack; |
57 int32_t _max_stack; |
52 |
58 |
53 u1 _flags; |
59 u1 _flags; |
54 VerificationType* _locals; // local variable type array |
60 VerificationType* _locals; // local variable type array |
55 VerificationType* _stack; // operand stack type array |
61 VerificationType* _stack; // operand stack type array |
56 |
62 |
57 ClassVerifier* _verifier; // the verifier verifying this method |
63 ClassVerifier* _verifier; // the verifier verifying this method |
|
64 |
|
65 StackMapFrame(const StackMapFrame& cp) : |
|
66 _offset(cp._offset), _locals_size(cp._locals_size), |
|
67 _stack_size(cp._stack_size), _stack_mark(cp._stack_mark), |
|
68 _max_locals(cp._max_locals), _max_stack(cp._max_stack), |
|
69 _flags(cp._flags) { |
|
70 _locals = NEW_RESOURCE_ARRAY(VerificationType, _max_locals); |
|
71 for (int i = 0; i < _max_locals; ++i) { |
|
72 if (i < _locals_size) { |
|
73 _locals[i] = cp._locals[i]; |
|
74 } else { |
|
75 _locals[i] = VerificationType::bogus_type(); |
|
76 } |
|
77 } |
|
78 int ss = MAX2(_stack_size, _stack_mark); |
|
79 _stack = NEW_RESOURCE_ARRAY(VerificationType, _max_stack); |
|
80 for (int i = 0; i < _max_stack; ++i) { |
|
81 if (i < ss) { |
|
82 _stack[i] = cp._stack[i]; |
|
83 } else { |
|
84 _stack[i] = VerificationType::bogus_type(); |
|
85 } |
|
86 } |
|
87 _verifier = NULL; |
|
88 } |
58 |
89 |
59 public: |
90 public: |
60 // constructors |
91 // constructors |
61 |
92 |
62 // This constructor is used by the type checker to allocate frames |
93 // This constructor is used by the type checker to allocate frames |
75 VerificationType* locals, |
106 VerificationType* locals, |
76 VerificationType* stack, |
107 VerificationType* stack, |
77 ClassVerifier* v) : _offset(offset), _flags(flags), |
108 ClassVerifier* v) : _offset(offset), _flags(flags), |
78 _locals_size(locals_size), |
109 _locals_size(locals_size), |
79 _stack_size(stack_size), |
110 _stack_size(stack_size), |
|
111 _stack_mark(-1), |
80 _max_locals(max_locals), |
112 _max_locals(max_locals), |
81 _max_stack(max_stack), |
113 _max_stack(max_stack), |
82 _locals(locals), _stack(stack), |
114 _locals(locals), _stack(stack), |
83 _verifier(v) { } |
115 _verifier(v) { } |
84 |
116 |
|
117 static StackMapFrame* copy(StackMapFrame* smf) { |
|
118 return new StackMapFrame(*smf); |
|
119 } |
|
120 |
85 inline void set_offset(int32_t offset) { _offset = offset; } |
121 inline void set_offset(int32_t offset) { _offset = offset; } |
86 inline void set_verifier(ClassVerifier* v) { _verifier = v; } |
122 inline void set_verifier(ClassVerifier* v) { _verifier = v; } |
87 inline void set_flags(u1 flags) { _flags = flags; } |
123 inline void set_flags(u1 flags) { _flags = flags; } |
88 inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; } |
124 inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; } |
89 inline void set_stack_size(u2 stack_size) { _stack_size = stack_size; } |
125 inline void set_stack_size(u2 stack_size) { _stack_size = _stack_mark = stack_size; } |
90 inline void clear_stack() { _stack_size = 0; } |
126 inline void clear_stack() { _stack_size = 0; } |
91 inline int32_t offset() const { return _offset; } |
127 inline int32_t offset() const { return _offset; } |
92 inline ClassVerifier* verifier() const { return _verifier; } |
128 inline ClassVerifier* verifier() const { return _verifier; } |
93 inline u1 flags() const { return _flags; } |
129 inline u1 flags() const { return _flags; } |
94 inline int32_t locals_size() const { return _locals_size; } |
130 inline int32_t locals_size() const { return _locals_size; } |
132 |
168 |
133 // Copy stack type array in src into this stack type array. |
169 // Copy stack type array in src into this stack type array. |
134 void copy_stack(const StackMapFrame* src); |
170 void copy_stack(const StackMapFrame* src); |
135 |
171 |
136 // Return true if this stack map frame is assignable to target. |
172 // Return true if this stack map frame is assignable to target. |
137 bool is_assignable_to(const StackMapFrame* target, |
173 bool is_assignable_to( |
138 bool is_exception_handler, TRAPS) const; |
174 const StackMapFrame* target, bool is_exception_handler, |
|
175 ErrorContext* ctx, TRAPS) const; |
|
176 |
|
177 inline void set_mark() { |
|
178 #ifdef DEBUG |
|
179 // Put bogus type to indicate it's no longer valid. |
|
180 if (_stack_mark != -1) { |
|
181 for (int i = _stack_mark; i >= _stack_size; --i) { |
|
182 _stack[i] = VerificationType::bogus_type(); |
|
183 } |
|
184 } |
|
185 #endif // def DEBUG |
|
186 _stack_mark = _stack_size; |
|
187 } |
|
188 |
|
189 // Used when an error occurs and we want to reset the stack to the state |
|
190 // it was before operands were popped off. |
|
191 void restore() { |
|
192 if (_stack_mark != -1) { |
|
193 _stack_size = _stack_mark; |
|
194 } |
|
195 } |
139 |
196 |
140 // Push type into stack type array. |
197 // Push type into stack type array. |
141 inline void push_stack(VerificationType type, TRAPS) { |
198 inline void push_stack(VerificationType type, TRAPS) { |
142 assert(!type.is_check(), "Must be a real type"); |
199 assert(!type.is_check(), "Must be a real type"); |
143 if (_stack_size >= _max_stack) { |
200 if (_stack_size >= _max_stack) { |
144 verifier()->verify_error(_offset, "Operand stack overflow"); |
201 verifier()->verify_error( |
|
202 ErrorContext::stack_overflow(_offset, this), |
|
203 "Operand stack overflow"); |
145 return; |
204 return; |
146 } |
205 } |
147 _stack[_stack_size++] = type; |
206 _stack[_stack_size++] = type; |
148 } |
207 } |
149 |
208 |
150 inline void push_stack_2( |
209 inline void push_stack_2( |
151 VerificationType type1, VerificationType type2, TRAPS) { |
210 VerificationType type1, VerificationType type2, TRAPS) { |
152 assert(type1.is_long() || type1.is_double(), "must be long/double"); |
211 assert(type1.is_long() || type1.is_double(), "must be long/double"); |
153 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); |
212 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); |
154 if (_stack_size >= _max_stack - 1) { |
213 if (_stack_size >= _max_stack - 1) { |
155 verifier()->verify_error(_offset, "Operand stack overflow"); |
214 verifier()->verify_error( |
|
215 ErrorContext::stack_overflow(_offset, this), |
|
216 "Operand stack overflow"); |
156 return; |
217 return; |
157 } |
218 } |
158 _stack[_stack_size++] = type1; |
219 _stack[_stack_size++] = type1; |
159 _stack[_stack_size++] = type2; |
220 _stack[_stack_size++] = type2; |
160 } |
221 } |
161 |
222 |
162 // Pop and return the top type on stack without verifying. |
223 // Pop and return the top type on stack without verifying. |
163 inline VerificationType pop_stack(TRAPS) { |
224 inline VerificationType pop_stack(TRAPS) { |
164 if (_stack_size <= 0) { |
225 if (_stack_size <= 0) { |
165 verifier()->verify_error(_offset, "Operand stack underflow"); |
226 verifier()->verify_error( |
|
227 ErrorContext::stack_underflow(_offset, this), |
|
228 "Operand stack underflow"); |
166 return VerificationType::bogus_type(); |
229 return VerificationType::bogus_type(); |
167 } |
230 } |
168 // Put bogus type to indicate it's no longer valid. |
|
169 // Added to make it consistent with the other pop_stack method. |
|
170 VerificationType top = _stack[--_stack_size]; |
231 VerificationType top = _stack[--_stack_size]; |
171 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) |
|
172 return top; |
232 return top; |
173 } |
233 } |
174 |
234 |
175 // Pop and return the top type on stack type array after verifying it |
235 // Pop and return the top type on stack type array after verifying it |
176 // is assignable to type. |
236 // is assignable to type. |
197 bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); |
256 bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); |
198 VerificationType top2 = _stack[_stack_size - 2]; |
257 VerificationType top2 = _stack[_stack_size - 2]; |
199 bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); |
258 bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); |
200 if (subtype1 && subtype2) { |
259 if (subtype1 && subtype2) { |
201 _stack_size -= 2; |
260 _stack_size -= 2; |
202 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) |
|
203 NOT_PRODUCT( _stack[_stack_size+1] = VerificationType::bogus_type(); ) |
|
204 return; |
261 return; |
205 } |
262 } |
206 } |
263 } |
207 pop_stack_ex(type1, THREAD); |
264 pop_stack_ex(type1, THREAD); |
208 pop_stack_ex(type2, THREAD); |
265 pop_stack_ex(type2, THREAD); |
|
266 } |
|
267 |
|
268 VerificationType local_at(int index) { |
|
269 return _locals[index]; |
|
270 } |
|
271 |
|
272 VerificationType stack_at(int index) { |
|
273 return _stack[index]; |
209 } |
274 } |
210 |
275 |
211 // Uncommon case that throws exceptions. |
276 // Uncommon case that throws exceptions. |
212 VerificationType pop_stack_ex(VerificationType type, TRAPS); |
277 VerificationType pop_stack_ex(VerificationType type, TRAPS); |
213 |
278 |
224 void set_local_2( |
289 void set_local_2( |
225 int32_t index, VerificationType type1, VerificationType type2, TRAPS); |
290 int32_t index, VerificationType type1, VerificationType type2, TRAPS); |
226 |
291 |
227 // Private auxiliary method used only in is_assignable_to(StackMapFrame). |
292 // Private auxiliary method used only in is_assignable_to(StackMapFrame). |
228 // Returns true if src is assignable to target. |
293 // Returns true if src is assignable to target. |
229 bool is_assignable_to( |
294 int is_assignable_to( |
230 VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; |
295 VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; |
231 |
296 |
232 bool has_flag_match_exception(const StackMapFrame* target) const; |
297 bool has_flag_match_exception(const StackMapFrame* target) const; |
233 |
298 |
234 // Debugging |
299 TypeOrigin stack_top_ctx(); |
235 void print() const PRODUCT_RETURN; |
300 |
|
301 void print_on(outputStream* str) const; |
236 }; |
302 }; |
237 |
303 |
238 #endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP |
304 #endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP |