comparison src/share/vm/classfile/stackMapFrame.cpp @ 24088:02a3d0dcbedd jdk8u121-b08

8167104: Additional class construction refinements Reviewed-by: hseigel
author kevinw
date Wed, 02 Nov 2016 14:54:53 -0700
parents 8cb56c8cb30d
children
comparison
equal deleted inserted replaced
24087:c7b69bdda4d7 24088:02a3d0dcbedd
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.
153 } 153 }
154 } 154 }
155 return i; 155 return i;
156 } 156 }
157 157
158 bool StackMapFrame::has_flag_match_exception(
159 const StackMapFrame* target) const {
160 // We allow flags of {UninitThis} to assign to {} if-and-only-if the
161 // target frame does not depend upon the current type.
162 // This is slightly too strict, as we need only enforce that the
163 // slots that were initialized by the <init> (the things that were
164 // UninitializedThis before initialize_object() converted them) are unused.
165 // However we didn't save that information so we'll enforce this upon
166 // anything that might have been initialized. This is a rare situation
167 // and javac never generates code that would end up here, but some profilers
168 // (such as NetBeans) might, when adding exception handlers in <init>
169 // methods to cover the invokespecial instruction. See 7020118.
170
171 assert(max_locals() == target->max_locals() &&
172 stack_size() == target->stack_size(), "StackMap sizes must match");
173
174 VerificationType top = VerificationType::top_type();
175 VerificationType this_type = verifier()->current_type();
176
177 if (!flag_this_uninit() || target->flags() != 0) {
178 return false;
179 }
180
181 for (int i = 0; i < target->locals_size(); ++i) {
182 if (locals()[i] == this_type && target->locals()[i] != top) {
183 return false;
184 }
185 }
186
187 for (int i = 0; i < target->stack_size(); ++i) {
188 if (stack()[i] == this_type && target->stack()[i] != top) {
189 return false;
190 }
191 }
192
193 return true;
194 }
195
196 bool StackMapFrame::is_assignable_to( 158 bool StackMapFrame::is_assignable_to(
197 const StackMapFrame* target, bool is_exception_handler, 159 const StackMapFrame* target, ErrorContext* ctx, TRAPS) const {
198 ErrorContext* ctx, TRAPS) const {
199 if (_max_locals != target->max_locals()) { 160 if (_max_locals != target->max_locals()) {
200 *ctx = ErrorContext::locals_size_mismatch( 161 *ctx = ErrorContext::locals_size_mismatch(
201 _offset, (StackMapFrame*)this, (StackMapFrame*)target); 162 _offset, (StackMapFrame*)this, (StackMapFrame*)target);
202 return false; 163 return false;
203 } 164 }
224 TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this), 185 TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
225 TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target)); 186 TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
226 return false; 187 return false;
227 } 188 }
228 189
229 bool match_flags = (_flags | target->flags()) == target->flags(); 190 if ((_flags | target->flags()) == target->flags()) {
230 if (match_flags || is_exception_handler && has_flag_match_exception(target)) {
231 return true; 191 return true;
232 } else { 192 } else {
233 *ctx = ErrorContext::bad_flags(target->offset(), 193 *ctx = ErrorContext::bad_flags(target->offset(),
234 (StackMapFrame*)this, (StackMapFrame*)target); 194 (StackMapFrame*)this, (StackMapFrame*)target);
235 return false; 195 return false;