hotspot/src/share/vm/classfile/stackMapFrame.hpp
changeset 13476 471200fb94fd
parent 9133 1c8d07466fdb
child 13728 882756847a04
equal deleted inserted replaced
13475:27f1abd05ae9 13476:471200fb94fd
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    32 #include "runtime/signature.hpp"
    32 #include "runtime/signature.hpp"
    33 #include "utilities/exceptions.hpp"
    33 #include "utilities/exceptions.hpp"
    34 
    34 
    35 // A StackMapFrame represents one frame in the stack map attribute.
    35 // A StackMapFrame represents one frame in the stack map attribute.
    36 
    36 
       
    37 class TypeContext;
       
    38 
    37 enum {
    39 enum {
    38   FLAG_THIS_UNINIT = 0x01
    40   FLAG_THIS_UNINIT = 0x01
    39 };
    41 };
    40 
    42 
    41 class StackMapFrame : public ResourceObj {
    43 class StackMapFrame : public ResourceObj {
    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.
   178     if (_stack_size != 0) {
   238     if (_stack_size != 0) {
   179       VerificationType top = _stack[_stack_size - 1];
   239       VerificationType top = _stack[_stack_size - 1];
   180       bool subtype = type.is_assignable_from(
   240       bool subtype = type.is_assignable_from(
   181         top, verifier(), CHECK_(VerificationType::bogus_type()));
   241         top, verifier(), CHECK_(VerificationType::bogus_type()));
   182       if (subtype) {
   242       if (subtype) {
   183         _stack_size --;
   243         --_stack_size;
   184         NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
       
   185         return top;
   244         return top;
   186       }
   245       }
   187     }
   246     }
   188     return pop_stack_ex(type, THREAD);
   247     return pop_stack_ex(type, THREAD);
   189   }
   248   }
   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