stackMapFrame.hpp revision 3602:da91efe96a93
1100966Siwasaki/* 2100966Siwasaki * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3100966Siwasaki * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4100966Siwasaki * 5100966Siwasaki * This code is free software; you can redistribute it and/or modify it 6100966Siwasaki * under the terms of the GNU General Public License version 2 only, as 7217365Sjkim * published by the Free Software Foundation. 8217365Sjkim * 9100966Siwasaki * This code is distributed in the hope that it will be useful, but WITHOUT 10100966Siwasaki * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11217365Sjkim * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12217365Sjkim * version 2 for more details (a copy is included in the LICENSE file that 13217365Sjkim * accompanied this code). 14217365Sjkim * 15217365Sjkim * You should have received a copy of the GNU General Public License version 16217365Sjkim * 2 along with this work; if not, write to the Free Software Foundation, 17217365Sjkim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18217365Sjkim * 19217365Sjkim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20217365Sjkim * or visit www.oracle.com if you need additional information or have any 21217365Sjkim * questions. 22217365Sjkim * 23217365Sjkim */ 24217365Sjkim 25100966Siwasaki#ifndef SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP 26217365Sjkim#define SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP 27217365Sjkim 28217365Sjkim#include "classfile/verificationType.hpp" 29100966Siwasaki#include "classfile/verifier.hpp" 30217365Sjkim#include "oops/method.hpp" 31217365Sjkim#include "runtime/handles.hpp" 32217365Sjkim#include "runtime/signature.hpp" 33217365Sjkim#include "utilities/exceptions.hpp" 34217365Sjkim 35217365Sjkim// A StackMapFrame represents one frame in the stack map attribute. 36217365Sjkim 37217365Sjkimclass TypeContext; 38217365Sjkim 39217365Sjkimenum { 40217365Sjkim FLAG_THIS_UNINIT = 0x01 41217365Sjkim}; 42217365Sjkim 43100966Siwasakiclass StackMapFrame : public ResourceObj { 44100966Siwasaki private: 45100966Siwasaki int32_t _offset; 46100966Siwasaki 47193341Sjkim // See comment in StackMapTable about _frame_count about why these 48100966Siwasaki // fields are int32_t instead of u2. 49100966Siwasaki int32_t _locals_size; // number of valid type elements in _locals 50100966Siwasaki int32_t _stack_size; // number of valid type elements in _stack 51100966Siwasaki 52100966Siwasaki int32_t _stack_mark; // Records the size of the stack prior to an 53100966Siwasaki // instruction modification, to allow rewinding 54167802Sjkim // when/if an error occurs. 55100966Siwasaki 56217365Sjkim int32_t _max_locals; 57217365Sjkim int32_t _max_stack; 58217365Sjkim 59217365Sjkim u1 _flags; 60217365Sjkim VerificationType* _locals; // local variable type array 61128212Snjl VerificationType* _stack; // operand stack type array 62217365Sjkim 63167802Sjkim ClassVerifier* _verifier; // the verifier verifying this method 64167802Sjkim 65167802Sjkim StackMapFrame(const StackMapFrame& cp) : 66167802Sjkim _offset(cp._offset), _locals_size(cp._locals_size), 67167802Sjkim _stack_size(cp._stack_size), _stack_mark(cp._stack_mark), 68209746Sjkim _max_locals(cp._max_locals), _max_stack(cp._max_stack), 69100966Siwasaki _flags(cp._flags) { 70167802Sjkim _locals = NEW_RESOURCE_ARRAY(VerificationType, _max_locals); 71100966Siwasaki for (int i = 0; i < _max_locals; ++i) { 72209746Sjkim if (i < _locals_size) { 73209746Sjkim _locals[i] = cp._locals[i]; 74209746Sjkim } else { 75209746Sjkim _locals[i] = VerificationType::bogus_type(); 76209746Sjkim } 77209746Sjkim } 78209746Sjkim int ss = MAX2(_stack_size, _stack_mark); 79209746Sjkim _stack = NEW_RESOURCE_ARRAY(VerificationType, _max_stack); 80209746Sjkim for (int i = 0; i < _max_stack; ++i) { 81167802Sjkim if (i < ss) { 82167802Sjkim _stack[i] = cp._stack[i]; 83167802Sjkim } else { 84167802Sjkim _stack[i] = VerificationType::bogus_type(); 85167802Sjkim } 86167802Sjkim } 87167802Sjkim _verifier = NULL; 88167802Sjkim } 89167802Sjkim 90167802Sjkim public: 91167802Sjkim // constructors 92167802Sjkim 93167802Sjkim // This constructor is used by the type checker to allocate frames 94167802Sjkim // in type state, which have _max_locals and _max_stack array elements 95167802Sjkim // in _locals and _stack. 96167802Sjkim StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* verifier); 97167802Sjkim 98167802Sjkim // This constructor is used to initialize stackmap frames in stackmap table, 99167802Sjkim // which have _locals_size and _stack_size array elements in _locals and _stack. 100167802Sjkim StackMapFrame(int32_t offset, 101167802Sjkim u1 flags, 102167802Sjkim u2 locals_size, 103167802Sjkim u2 stack_size, 104167802Sjkim u2 max_locals, 105167802Sjkim u2 max_stack, 106167802Sjkim VerificationType* locals, 107167802Sjkim VerificationType* stack, 108193267Sjkim ClassVerifier* v) : _offset(offset), _flags(flags), 109193267Sjkim _locals_size(locals_size), 110193267Sjkim _stack_size(stack_size), 111193267Sjkim _stack_mark(-1), 112193267Sjkim _max_locals(max_locals), 113193267Sjkim _max_stack(max_stack), 114193267Sjkim _locals(locals), _stack(stack), 115193267Sjkim _verifier(v) { } 116193267Sjkim 117193267Sjkim static StackMapFrame* copy(StackMapFrame* smf) { 118197104Sjkim return new StackMapFrame(*smf); 119197104Sjkim } 120209746Sjkim 121209746Sjkim inline void set_offset(int32_t offset) { _offset = offset; } 122209746Sjkim inline void set_verifier(ClassVerifier* v) { _verifier = v; } 123209746Sjkim inline void set_flags(u1 flags) { _flags = flags; } 124209746Sjkim inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; } 125209746Sjkim inline void set_stack_size(u2 stack_size) { _stack_size = _stack_mark = stack_size; } 126216471Sjkim inline void clear_stack() { _stack_size = 0; } 127217365Sjkim inline int32_t offset() const { return _offset; } 128217365Sjkim inline ClassVerifier* verifier() const { return _verifier; } 129217365Sjkim inline u1 flags() const { return _flags; } 130167802Sjkim inline int32_t locals_size() const { return _locals_size; } 131197104Sjkim inline VerificationType* locals() const { return _locals; } 132167802Sjkim inline int32_t stack_size() const { return _stack_size; } 133193267Sjkim inline VerificationType* stack() const { return _stack; } 134167802Sjkim inline int32_t max_locals() const { return _max_locals; } 135167802Sjkim inline int32_t max_stack() const { return _max_stack; } 136209746Sjkim inline bool flag_this_uninit() const { return _flags & FLAG_THIS_UNINIT; } 137209746Sjkim 138209746Sjkim // Set locals and stack types to bogus 139209746Sjkim inline void reset() { 140167802Sjkim int32_t i; 141167802Sjkim for (i = 0; i < _max_locals; i++) { 142167802Sjkim _locals[i] = VerificationType::bogus_type(); 143193267Sjkim } 144193267Sjkim for (i = 0; i < _max_stack; i++) { 145209746Sjkim _stack[i] = VerificationType::bogus_type(); 146209746Sjkim } 147167802Sjkim } 148167802Sjkim 149167802Sjkim // Return a StackMapFrame with the same local variable array and empty stack. 150167802Sjkim // Stack array is allocate with unused one element. 151167802Sjkim StackMapFrame* frame_in_exception_handler(u1 flags); 152100966Siwasaki 153100966Siwasaki // Set local variable type array based on m's signature. 154100966Siwasaki VerificationType set_locals_from_arg( 155167802Sjkim const methodHandle m, VerificationType thisKlass, TRAPS); 156167802Sjkim 157100966Siwasaki // Search local variable type array and stack type array. 158167802Sjkim // Return true if an uninitialized object is found. 159151937Sjkim bool has_new_object() const; 160100966Siwasaki 161100966Siwasaki // Search local variable type array and stack type array. 162100966Siwasaki // Set every element with type of old_object to new_object. 163209746Sjkim void initialize_object( 164209746Sjkim VerificationType old_object, VerificationType new_object); 165209746Sjkim 166209746Sjkim // Copy local variable type array in src into this local variable type array. 167100966Siwasaki void copy_locals(const StackMapFrame* src); 168100966Siwasaki 169100966Siwasaki // Copy stack type array in src into this stack type array. 170100966Siwasaki void copy_stack(const StackMapFrame* src); 171100966Siwasaki 172209746Sjkim // Return true if this stack map frame is assignable to target. 173209746Sjkim bool is_assignable_to( 174100966Siwasaki const StackMapFrame* target, bool is_exception_handler, 175209746Sjkim ErrorContext* ctx, TRAPS) const; 176167802Sjkim 177167802Sjkim inline void set_mark() { 178167802Sjkim#ifdef DEBUG 179167802Sjkim // Put bogus type to indicate it's no longer valid. 180100966Siwasaki if (_stack_mark != -1) { 181167802Sjkim for (int i = _stack_mark; i >= _stack_size; --i) { 182167802Sjkim _stack[i] = VerificationType::bogus_type(); 183167802Sjkim } 184167802Sjkim } 185167802Sjkim#endif // def DEBUG 186167802Sjkim _stack_mark = _stack_size; 187167802Sjkim } 188167802Sjkim 189167802Sjkim // Used when an error occurs and we want to reset the stack to the state 190167802Sjkim // it was before operands were popped off. 191167802Sjkim void restore() { 192167802Sjkim if (_stack_mark != -1) { 193167802Sjkim _stack_size = _stack_mark; 194167802Sjkim } 195167802Sjkim } 196167802Sjkim 197167802Sjkim // Push type into stack type array. 198167802Sjkim inline void push_stack(VerificationType type, TRAPS) { 199167802Sjkim assert(!type.is_check(), "Must be a real type"); 200167802Sjkim if (_stack_size >= _max_stack) { 201193267Sjkim verifier()->verify_error( 202167802Sjkim ErrorContext::stack_overflow(_offset, this), 203167802Sjkim "Operand stack overflow"); 204167802Sjkim return; 205167802Sjkim } 206167802Sjkim _stack[_stack_size++] = type; 207167802Sjkim } 208167802Sjkim 209167802Sjkim inline void push_stack_2( 210193267Sjkim VerificationType type1, VerificationType type2, TRAPS) { 211197104Sjkim assert(type1.is_long() || type1.is_double(), "must be long/double"); 212167802Sjkim assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 213193267Sjkim if (_stack_size >= _max_stack - 1) { 214193267Sjkim verifier()->verify_error( 215193267Sjkim ErrorContext::stack_overflow(_offset, this), 216209746Sjkim "Operand stack overflow"); 217167802Sjkim return; 218167802Sjkim } 219167802Sjkim _stack[_stack_size++] = type1; 220193267Sjkim _stack[_stack_size++] = type2; 221167802Sjkim } 222167802Sjkim 223193267Sjkim // Pop and return the top type on stack without verifying. 224193267Sjkim inline VerificationType pop_stack(TRAPS) { 225193267Sjkim if (_stack_size <= 0) { 226197104Sjkim verifier()->verify_error( 227193267Sjkim ErrorContext::stack_underflow(_offset, this), 228193267Sjkim "Operand stack underflow"); 229193267Sjkim return VerificationType::bogus_type(); 230193267Sjkim } 231193267Sjkim VerificationType top = _stack[--_stack_size]; 232197104Sjkim return top; 233167802Sjkim } 234197104Sjkim 235197104Sjkim // Pop and return the top type on stack type array after verifying it 236197104Sjkim // is assignable to type. 237197104Sjkim inline VerificationType pop_stack(VerificationType type, TRAPS) { 238197104Sjkim if (_stack_size != 0) { 239197104Sjkim VerificationType top = _stack[_stack_size - 1]; 240197104Sjkim bool subtype = type.is_assignable_from( 241197104Sjkim top, verifier(), CHECK_(VerificationType::bogus_type())); 242167802Sjkim if (subtype) { 243167802Sjkim --_stack_size; 244167802Sjkim return top; 245167802Sjkim } 246167802Sjkim } 247167802Sjkim return pop_stack_ex(type, THREAD); 248167802Sjkim } 249167802Sjkim 250167802Sjkim inline void pop_stack_2( 251167802Sjkim VerificationType type1, VerificationType type2, TRAPS) { 252193267Sjkim assert(type1.is_long2() || type1.is_double2(), "must be long/double"); 253193267Sjkim assert(type2.is_long() || type2.is_double(), "must be long/double_2"); 254167802Sjkim if (_stack_size >= 2) { 255167802Sjkim VerificationType top1 = _stack[_stack_size - 1]; 256167802Sjkim bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); 257204773Sjkim VerificationType top2 = _stack[_stack_size - 2]; 258197104Sjkim bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); 259197104Sjkim if (subtype1 && subtype2) { 260167802Sjkim _stack_size -= 2; 261167802Sjkim return; 262167802Sjkim } 263193267Sjkim } 264167802Sjkim pop_stack_ex(type1, THREAD); 265167802Sjkim pop_stack_ex(type2, THREAD); 266167802Sjkim } 267167802Sjkim 268193267Sjkim VerificationType local_at(int index) { 269167802Sjkim return _locals[index]; 270167802Sjkim } 271193267Sjkim 272167802Sjkim VerificationType stack_at(int index) { 273197104Sjkim return _stack[index]; 274197104Sjkim } 275197104Sjkim 276197104Sjkim // Uncommon case that throws exceptions. 277209746Sjkim VerificationType pop_stack_ex(VerificationType type, TRAPS); 278167802Sjkim 279167802Sjkim // Return the type at index in local variable array after verifying 280217365Sjkim // it is assignable to type. 281167802Sjkim VerificationType get_local(int32_t index, VerificationType type, TRAPS); 282217365Sjkim // For long/double. 283100966Siwasaki void get_local_2( 284167802Sjkim int32_t index, VerificationType type1, VerificationType type2, TRAPS); 285167802Sjkim 286209746Sjkim // Set element at index in local variable array to type. 287209746Sjkim void set_local(int32_t index, VerificationType type, TRAPS); 288209746Sjkim // For long/double. 289209746Sjkim void set_local_2( 290209746Sjkim int32_t index, VerificationType type1, VerificationType type2, TRAPS); 291209746Sjkim 292209746Sjkim // Private auxiliary method used only in is_assignable_to(StackMapFrame). 293209746Sjkim // Returns true if src is assignable to target. 294209746Sjkim int is_assignable_to( 295209746Sjkim VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; 296209746Sjkim 297209746Sjkim bool has_flag_match_exception(const StackMapFrame* target) const; 298167802Sjkim 299167802Sjkim TypeOrigin stack_top_ctx(); 300167802Sjkim 301167802Sjkim void print_on(outputStream* str) const; 302193267Sjkim}; 303167802Sjkim 304167802Sjkim#endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP 305167802Sjkim