1 /* |
1 /* |
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2016, 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. |
68 return i; // frame with offset doesn't exist in the array |
68 return i; // frame with offset doesn't exist in the array |
69 } |
69 } |
70 |
70 |
71 bool StackMapTable::match_stackmap( |
71 bool StackMapTable::match_stackmap( |
72 StackMapFrame* frame, int32_t target, |
72 StackMapFrame* frame, int32_t target, |
73 bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { |
73 bool match, bool update, ErrorContext* ctx, TRAPS) const { |
74 int index = get_index_from_offset(target); |
74 int index = get_index_from_offset(target); |
75 return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); |
75 return match_stackmap(frame, target, index, match, update, ctx, THREAD); |
76 } |
76 } |
77 |
77 |
78 // Match and/or update current_frame to the frame in stackmap table with |
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. |
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 // |
80 // |
82 // The values of match and update are: _match__update__handler |
81 // The values of match and update are: _match__update |
83 // |
82 // |
84 // checking a branch target: true false false |
83 // checking a branch target: true false |
85 // checking an exception handler: true false true |
84 // checking an exception handler: true false |
86 // linear bytecode verification following an |
85 // linear bytecode verification following an |
87 // unconditional branch: false true false |
86 // unconditional branch: false true |
88 // linear bytecode verification not following an |
87 // linear bytecode verification not following an |
89 // unconditional branch: true true false |
88 // unconditional branch: true true |
90 bool StackMapTable::match_stackmap( |
89 bool StackMapTable::match_stackmap( |
91 StackMapFrame* frame, int32_t target, int32_t frame_index, |
90 StackMapFrame* frame, int32_t target, int32_t frame_index, |
92 bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { |
91 bool match, bool update, ErrorContext* ctx, TRAPS) const { |
93 if (frame_index < 0 || frame_index >= _frame_count) { |
92 if (frame_index < 0 || frame_index >= _frame_count) { |
94 *ctx = ErrorContext::missing_stackmap(frame->offset()); |
93 *ctx = ErrorContext::missing_stackmap(frame->offset()); |
95 frame->verifier()->verify_error( |
94 frame->verifier()->verify_error( |
96 *ctx, "Expecting a stackmap frame at branch target %d", target); |
95 *ctx, "Expecting a stackmap frame at branch target %d", target); |
97 return false; |
96 return false; |
100 StackMapFrame *stackmap_frame = _frame_array[frame_index]; |
99 StackMapFrame *stackmap_frame = _frame_array[frame_index]; |
101 bool result = true; |
100 bool result = true; |
102 if (match) { |
101 if (match) { |
103 // Has direct control flow from last instruction, need to match the two |
102 // Has direct control flow from last instruction, need to match the two |
104 // frames. |
103 // frames. |
105 result = frame->is_assignable_to(stackmap_frame, handler, |
104 result = frame->is_assignable_to(stackmap_frame, |
106 ctx, CHECK_VERIFY_(frame->verifier(), result)); |
105 ctx, CHECK_VERIFY_(frame->verifier(), result)); |
107 } |
106 } |
108 if (update) { |
107 if (update) { |
109 // Use the frame in stackmap table as current frame |
108 // Use the frame in stackmap table as current frame |
110 int lsize = stackmap_frame->locals_size(); |
109 int lsize = stackmap_frame->locals_size(); |
124 |
123 |
125 void StackMapTable::check_jump_target( |
124 void StackMapTable::check_jump_target( |
126 StackMapFrame* frame, int32_t target, TRAPS) const { |
125 StackMapFrame* frame, int32_t target, TRAPS) const { |
127 ErrorContext ctx; |
126 ErrorContext ctx; |
128 bool match = match_stackmap( |
127 bool match = match_stackmap( |
129 frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); |
128 frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); |
130 if (!match || (target < 0 || target >= _code_length)) { |
129 if (!match || (target < 0 || target >= _code_length)) { |
131 frame->verifier()->verify_error(ctx, |
130 frame->verifier()->verify_error(ctx, |
132 "Inconsistent stackmap frames at branch target %d", target); |
131 "Inconsistent stackmap frames at branch target %d", target); |
133 } |
132 } |
134 } |
133 } |