src/share/vm/classfile/stackMapTable.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_8051012 Sdiff src/share/vm/classfile

src/share/vm/classfile/stackMapTable.cpp

Print this page




  53       }
  54       pre_frame = frame;
  55     }
  56   }
  57   reader->check_end(CHECK);
  58 }
  59 
  60 // This method is only called by method in StackMapTable.
  61 int StackMapTable::get_index_from_offset(int32_t offset) const {
  62   int i = 0;
  63   for (; i < _frame_count; i++) {
  64     if (_frame_array[i]->offset() == offset) {
  65       return i;
  66     }
  67   }
  68   return i;  // frame with offset doesn't exist in the array
  69 }
  70 
  71 bool StackMapTable::match_stackmap(
  72     StackMapFrame* frame, int32_t target,
  73     bool match, bool update, ErrorContext* ctx, TRAPS) const {
  74   int index = get_index_from_offset(target);
  75   return match_stackmap(frame, target, index, match, update, ctx, THREAD);
  76 }
  77 
  78 // Match and/or update current_frame to the frame in stackmap table with
  79 // specified offset and frame index. Return true if the two frames match.

  80 //
  81 // The values of match and update are:                  _match__update_
  82 //
  83 // checking a branch target/exception handler:           true   false

  84 // linear bytecode verification following an
  85 // unconditional branch:                                 false  true
  86 // linear bytecode verification not following an
  87 // unconditional branch:                                 true   true
  88 bool StackMapTable::match_stackmap(
  89     StackMapFrame* frame, int32_t target, int32_t frame_index,
  90     bool match, bool update, ErrorContext* ctx, TRAPS) const {
  91   if (frame_index < 0 || frame_index >= _frame_count) {
  92     *ctx = ErrorContext::missing_stackmap(frame->offset());
  93     frame->verifier()->verify_error(
  94         *ctx, "Expecting a stackmap frame at branch target %d", target);
  95     return false;
  96   }
  97 
  98   StackMapFrame *stackmap_frame = _frame_array[frame_index];
  99   bool result = true;
 100   if (match) {
 101     // when checking handler target, match == true && update == false
 102     bool is_exception_handler = !update;
 103     // Has direct control flow from last instruction, need to match the two
 104     // frames.
 105     result = frame->is_assignable_to(stackmap_frame, is_exception_handler,
 106         ctx, CHECK_VERIFY_(frame->verifier(), result));
 107   }
 108   if (update) {
 109     // Use the frame in stackmap table as current frame
 110     int lsize = stackmap_frame->locals_size();
 111     int ssize = stackmap_frame->stack_size();
 112     if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
 113       // Make sure unused type array items are all _bogus_type.
 114       frame->reset();
 115     }
 116     frame->set_locals_size(lsize);
 117     frame->copy_locals(stackmap_frame);
 118     frame->set_stack_size(ssize);
 119     frame->copy_stack(stackmap_frame);
 120     frame->set_flags(stackmap_frame->flags());
 121   }
 122   return result;
 123 }
 124 
 125 void StackMapTable::check_jump_target(
 126     StackMapFrame* frame, int32_t target, TRAPS) const {
 127   ErrorContext ctx;
 128   bool match = match_stackmap(
 129     frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
 130   if (!match || (target < 0 || target >= _code_length)) {
 131     frame->verifier()->verify_error(ctx,
 132         "Inconsistent stackmap frames at branch target %d", target);
 133     return;
 134   }
 135   // check if uninitialized objects exist on backward branches
 136   check_new_object(frame, target, CHECK_VERIFY(frame->verifier()));
 137   frame->verifier()->update_furthest_jump(target);
 138 }
 139 
 140 void StackMapTable::check_new_object(
 141     const StackMapFrame* frame, int32_t target, TRAPS) const {
 142   if (frame->offset() > target && frame->has_new_object()) {
 143     frame->verifier()->verify_error(
 144         ErrorContext::bad_code(frame->offset()),
 145         "Uninitialized object exists on backward branch %d", target);
 146     return;
 147   }
 148 }
 149 
 150 void StackMapTable::print_on(outputStream* str) const {
 151   str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
 152   str->indent().print_cr("table = { ");
 153   {
 154     streamIndentor si(str);
 155     for (int32_t i = 0; i < _frame_count; ++i) {
 156       _frame_array[i]->print_on(str);
 157     }




  53       }
  54       pre_frame = frame;
  55     }
  56   }
  57   reader->check_end(CHECK);
  58 }
  59 
  60 // This method is only called by method in StackMapTable.
  61 int StackMapTable::get_index_from_offset(int32_t offset) const {
  62   int i = 0;
  63   for (; i < _frame_count; i++) {
  64     if (_frame_array[i]->offset() == offset) {
  65       return i;
  66     }
  67   }
  68   return i;  // frame with offset doesn't exist in the array
  69 }
  70 
  71 bool StackMapTable::match_stackmap(
  72     StackMapFrame* frame, int32_t target,
  73     bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
  74   int index = get_index_from_offset(target);
  75   return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD);
  76 }
  77 
  78 // Match and/or update current_frame to the frame in stackmap table with
  79 // specified offset and frame index. Return true if the two frames match.
  80 // handler is true if the frame in stackmap_table is for an exception handler.
  81 //
  82 // The values of match and update are:                  _match__update__handler
  83 //
  84 // checking a branch target:                             true   false   false
  85 // checking an exception handler:                        true   false   true
  86 // linear bytecode verification following an
  87 // unconditional branch:                                 false  true    false
  88 // linear bytecode verification not following an
  89 // unconditional branch:                                 true   true    false
  90 bool StackMapTable::match_stackmap(
  91     StackMapFrame* frame, int32_t target, int32_t frame_index,
  92     bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
  93   if (frame_index < 0 || frame_index >= _frame_count) {
  94     *ctx = ErrorContext::missing_stackmap(frame->offset());
  95     frame->verifier()->verify_error(
  96         *ctx, "Expecting a stackmap frame at branch target %d", target);
  97     return false;
  98   }
  99 
 100   StackMapFrame *stackmap_frame = _frame_array[frame_index];
 101   bool result = true;
 102   if (match) {


 103     // Has direct control flow from last instruction, need to match the two
 104     // frames.
 105     result = frame->is_assignable_to(stackmap_frame, handler,
 106         ctx, CHECK_VERIFY_(frame->verifier(), result));
 107   }
 108   if (update) {
 109     // Use the frame in stackmap table as current frame
 110     int lsize = stackmap_frame->locals_size();
 111     int ssize = stackmap_frame->stack_size();
 112     if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
 113       // Make sure unused type array items are all _bogus_type.
 114       frame->reset();
 115     }
 116     frame->set_locals_size(lsize);
 117     frame->copy_locals(stackmap_frame);
 118     frame->set_stack_size(ssize);
 119     frame->copy_stack(stackmap_frame);
 120     frame->set_flags(stackmap_frame->flags());
 121   }
 122   return result;
 123 }
 124 
 125 void StackMapTable::check_jump_target(
 126     StackMapFrame* frame, int32_t target, TRAPS) const {
 127   ErrorContext ctx;
 128   bool match = match_stackmap(
 129     frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier()));
 130   if (!match || (target < 0 || target >= _code_length)) {
 131     frame->verifier()->verify_error(ctx,
 132         "Inconsistent stackmap frames at branch target %d", target);
 133     return;
 134   }
 135   // check if uninitialized objects exist on backward branches
 136   check_new_object(frame, target, CHECK_VERIFY(frame->verifier()));

 137 }
 138 
 139 void StackMapTable::check_new_object(
 140     const StackMapFrame* frame, int32_t target, TRAPS) const {
 141   if (frame->offset() > target && frame->has_new_object()) {
 142     frame->verifier()->verify_error(
 143         ErrorContext::bad_code(frame->offset()),
 144         "Uninitialized object exists on backward branch %d", target);
 145     return;
 146   }
 147 }
 148 
 149 void StackMapTable::print_on(outputStream* str) const {
 150   str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
 151   str->indent().print_cr("table = { ");
 152   {
 153     streamIndentor si(str);
 154     for (int32_t i = 0; i < _frame_count; ++i) {
 155       _frame_array[i]->print_on(str);
 156     }


src/share/vm/classfile/stackMapTable.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File