constMethod.cpp revision 8413:92457dfb91bd
1227569Sphilip/*
2301388Sarybchik * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3284555Sarybchik * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4227569Sphilip *
5227569Sphilip * This code is free software; you can redistribute it and/or modify it
6284555Sarybchik * under the terms of the GNU General Public License version 2 only, as
7227569Sphilip * published by the Free Software Foundation.
8284555Sarybchik *
9284555Sarybchik * This code is distributed in the hope that it will be useful, but WITHOUT
10284555Sarybchik * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11284555Sarybchik * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12284555Sarybchik * version 2 for more details (a copy is included in the LICENSE file that
13284555Sarybchik * accompanied this code).
14284555Sarybchik *
15284555Sarybchik * You should have received a copy of the GNU General Public License version
16284555Sarybchik * 2 along with this work; if not, write to the Free Software Foundation,
17284555Sarybchik * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18284555Sarybchik *
19284555Sarybchik * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20284555Sarybchik * or visit www.oracle.com if you need additional information or have any
21284555Sarybchik * questions.
22284555Sarybchik *
23284555Sarybchik */
24284555Sarybchik
25284555Sarybchik#include "precompiled.hpp"
26284555Sarybchik#include "gc/shared/gcLocker.hpp"
27284555Sarybchik#include "interpreter/interpreter.hpp"
28284555Sarybchik#include "memory/heapInspection.hpp"
29227569Sphilip#include "memory/metadataFactory.hpp"
30228078Sphilip#include "oops/constMethod.hpp"
31228078Sphilip#include "oops/method.hpp"
32228078Sphilip
33228078Sphilip// Static initialization
34227569Sphilipconst u2 ConstMethod::MAX_IDNUM   = 0xFFFE;
35227569Sphilipconst u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
36284555Sarybchik
37227569SphilipConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
38227569Sphilip                                   int byte_code_size,
39227569Sphilip                                   InlineTableSizes* sizes,
40311064Sarybchik                                   MethodType method_type,
41311064Sarybchik                                   TRAPS) {
42293927Sarybchik  int size = ConstMethod::size(byte_code_size, sizes);
43227569Sphilip  return new (loader_data, size, true, MetaspaceObj::ConstMethodType, THREAD) ConstMethod(
44227569Sphilip      byte_code_size, sizes, method_type, size);
45227569Sphilip}
46227569Sphilip
47227569SphilipConstMethod::ConstMethod(int byte_code_size,
48342516Sarybchik                         InlineTableSizes* sizes,
49342516Sarybchik                         MethodType method_type,
50293927Sarybchik                         int size) {
51227569Sphilip
52227569Sphilip  No_Safepoint_Verifier no_safepoint;
53284555Sarybchik  init_fingerprint();
54284555Sarybchik  set_constants(NULL);
55284555Sarybchik  set_stackmap_data(NULL);
56284555Sarybchik  set_code_size(byte_code_size);
57227569Sphilip  set_constMethod_size(size);
58227569Sphilip  set_inlined_tables_length(sizes); // sets _flags
59227569Sphilip  set_method_type(method_type);
60227569Sphilip  assert(this->size() == size, "wrong size for object");
61227569Sphilip  set_name_index(0);
62227569Sphilip  set_signature_index(0);
63227569Sphilip  set_constants(NULL);
64227569Sphilip  set_max_stack(0);
65227569Sphilip  set_max_locals(0);
66227569Sphilip  set_method_idnum(0);
67227569Sphilip  set_size_of_parameters(0);
68227569Sphilip}
69227569Sphilip
70227569Sphilip// Accessor that copies to metadata.
71227569Sphilipvoid ConstMethod::copy_stackmap_data(ClassLoaderData* loader_data,
72227569Sphilip                                     u1* sd, int length, TRAPS) {
73227569Sphilip  _stackmap_data = MetadataFactory::new_array<u1>(loader_data, length, CHECK);
74227569Sphilip  memcpy((void*)_stackmap_data->adr_at(0), (void*)sd, length);
75227569Sphilip}
76227569Sphilip
77293927Sarybchik// Deallocate metadata fields associated with ConstMethod*
78227569Sphilipvoid ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
79227569Sphilip  if (stackmap_data() != NULL) {
80227569Sphilip    MetadataFactory::free_array<u1>(loader_data, stackmap_data());
81227569Sphilip  }
82311064Sarybchik  set_stackmap_data(NULL);
83311064Sarybchik
84293927Sarybchik  // deallocate annotation arrays
85227569Sphilip  if (has_method_annotations())
86227569Sphilip    MetadataFactory::free_array<u1>(loader_data, method_annotations());
87227569Sphilip  if (has_parameter_annotations())
88227569Sphilip    MetadataFactory::free_array<u1>(loader_data, parameter_annotations());
89284555Sarybchik  if (has_type_annotations())
90284555Sarybchik    MetadataFactory::free_array<u1>(loader_data, type_annotations());
91284555Sarybchik  if (has_default_annotations())
92284555Sarybchik    MetadataFactory::free_array<u1>(loader_data, default_annotations());
93293927Sarybchik}
94227569Sphilip
95284555Sarybchik// How big must this constMethodObject be?
96284555Sarybchik
97284555Sarybchikint ConstMethod::size(int code_size,
98227569Sphilip                      InlineTableSizes* sizes) {
99284555Sarybchik  int extra_bytes = code_size;
100284555Sarybchik  if (sizes->compressed_linenumber_size() > 0) {
101227569Sphilip    extra_bytes += sizes->compressed_linenumber_size();
102227569Sphilip  }
103280550Sarybchik  if (sizes->checked_exceptions_length() > 0) {
104227569Sphilip    extra_bytes += sizeof(u2);
105284555Sarybchik    extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
106227569Sphilip  }
107311079Sarybchik  if (sizes->localvariable_table_length() > 0) {
108311079Sarybchik    extra_bytes += sizeof(u2);
109311079Sarybchik    extra_bytes +=
110311079Sarybchik              sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
111311079Sarybchik  }
112311079Sarybchik  if (sizes->exception_table_length() > 0) {
113311079Sarybchik    extra_bytes += sizeof(u2);
114280550Sarybchik    extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
115280550Sarybchik  }
116284555Sarybchik  if (sizes->generic_signature_index() != 0) {
117280550Sarybchik    extra_bytes += sizeof(u2);
118280550Sarybchik  }
119284555Sarybchik  // This has to be a less-than-or-equal check, because we might be
120284555Sarybchik  // storing information from a zero-length MethodParameters
121280550Sarybchik  // attribute.  We have to store these, because in some cases, they
122284555Sarybchik  // cause the reflection API to throw a MalformedParametersException.
123280550Sarybchik  if (sizes->method_parameters_length() >= 0) {
124280550Sarybchik    extra_bytes += sizeof(u2);
125280588Sarybchik    extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
126280588Sarybchik  }
127280588Sarybchik
128280588Sarybchik  // Align sizes up to a word.
129280550Sarybchik  extra_bytes = align_size_up(extra_bytes, BytesPerWord);
130284555Sarybchik
131284555Sarybchik  // One pointer per annotation array
132227569Sphilip  if (sizes->method_annotations_length() > 0) {
133284555Sarybchik    extra_bytes += sizeof(AnnotationArray*);
134284555Sarybchik  }
135284555Sarybchik  if (sizes->parameter_annotations_length() > 0) {
136227569Sphilip    extra_bytes += sizeof(AnnotationArray*);
137284555Sarybchik  }
138284555Sarybchik  if (sizes->type_annotations_length() > 0) {
139227569Sphilip    extra_bytes += sizeof(AnnotationArray*);
140311768Sarybchik  }
141311768Sarybchik  if (sizes->default_annotations_length() > 0) {
142311768Sarybchik    extra_bytes += sizeof(AnnotationArray*);
143311768Sarybchik  }
144284555Sarybchik
145284555Sarybchik  int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
146284555Sarybchik  assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned");
147284555Sarybchik  return align_object_size(header_size() + extra_words);
148284555Sarybchik}
149284555Sarybchik
150284555SarybchikMethod* ConstMethod::method() const {
151284555Sarybchik    return _constants->pool_holder()->method_with_idnum(_method_idnum);
152284555Sarybchik  }
153227569Sphilip
154284555Sarybchik// linenumber table - note that length is unknown until decompression,
155284555Sarybchik// see class CompressedLineNumberReadStream.
156284555Sarybchik
157227569Sphilipu_char* ConstMethod::compressed_linenumber_table() const {
158342480Sarybchik  // Located immediately following the bytecodes.
159342480Sarybchik  assert(has_linenumber_table(), "called only if table is present");
160227569Sphilip  return code_end();
161280562Sarybchik}
162280562Sarybchik
163227569Sphilip// Last short in ConstMethod* before annotations
164284555Sarybchiku2* ConstMethod::last_u2_element() const {
165284555Sarybchik  int offset = 0;
166294381Sarybchik  if (has_method_annotations()) offset++;
167311078Sarybchik  if (has_parameter_annotations()) offset++;
168293953Sarybchik  if (has_type_annotations()) offset++;
169284555Sarybchik  if (has_default_annotations()) offset++;
170301365Sarybchik  return (u2*)((AnnotationArray**)constMethod_end() - offset) - 1;
171301365Sarybchik}
172301365Sarybchik
173301365Sarybchiku2* ConstMethod::generic_signature_index_addr() const {
174311495Sarybchik  // Located at the end of the constMethod.
175311495Sarybchik  assert(has_generic_signature(), "called only if generic signature exists");
176227569Sphilip  return last_u2_element();
177227569Sphilip}
178227569Sphilip
179227569Sphilipu2* ConstMethod::method_parameters_length_addr() const {
180227569Sphilip  assert(has_method_parameters(), "called only if table is present");
181293927Sarybchik  return has_generic_signature() ? (last_u2_element() - 1) :
182227569Sphilip                                    last_u2_element();
183227569Sphilip}
184227569Sphilip
185227569Sphilipu2* ConstMethod::checked_exceptions_length_addr() const {
186293927Sarybchik  // Located immediately before the generic signature index.
187227569Sphilip  assert(has_checked_exceptions(), "called only if table is present");
188227569Sphilip  if(has_method_parameters()) {
189227569Sphilip    // If method parameters present, locate immediately before them.
190342495Sarybchik    return (u2*)method_parameters_start() - 1;
191227569Sphilip  } else {
192342495Sarybchik    // Else, the exception table is at the end of the constMethod.
193293927Sarybchik    return has_generic_signature() ? (last_u2_element() - 1) :
194227569Sphilip                                     last_u2_element();
195284555Sarybchik  }
196284555Sarybchik}
197227569Sphilip
198227569Sphilipu2* ConstMethod::exception_table_length_addr() const {
199227569Sphilip  assert(has_exception_handler(), "called only if table is present");
200227569Sphilip  if (has_checked_exceptions()) {
201284555Sarybchik    // If checked_exception present, locate immediately before them.
202227569Sphilip    return (u2*) checked_exceptions_start() - 1;
203227569Sphilip  } else {
204227569Sphilip    if(has_method_parameters()) {
205227569Sphilip      // If method parameters present, locate immediately before them.
206227569Sphilip      return (u2*)method_parameters_start() - 1;
207227569Sphilip    } else {
208293927Sarybchik      // Else, the exception table is at the end of the constMethod.
209227569Sphilip      return has_generic_signature() ? (last_u2_element() - 1) :
210227569Sphilip                                        last_u2_element();
211227569Sphilip    }
212227569Sphilip  }
213342507Sarybchik}
214342507Sarybchik
215342507Sarybchiku2* ConstMethod::localvariable_table_length_addr() const {
216342507Sarybchik  assert(has_localvariable_table(), "called only if table is present");
217342507Sarybchik  if (has_exception_handler()) {
218342507Sarybchik    // If exception_table present, locate immediately before them.
219342507Sarybchik    return (u2*) exception_table_start() - 1;
220342507Sarybchik  } else {
221342507Sarybchik    if (has_checked_exceptions()) {
222342507Sarybchik      // If checked_exception present, locate immediately before them.
223342507Sarybchik      return (u2*) checked_exceptions_start() - 1;
224342507Sarybchik    } else {
225342507Sarybchik      if(has_method_parameters()) {
226342507Sarybchik        // If method parameters present, locate immediately before them.
227342507Sarybchik        return (u2*)method_parameters_start() - 1;
228342507Sarybchik      } else {
229342507Sarybchik        // Else, the exception table is at the end of the constMethod.
230342507Sarybchik      return has_generic_signature() ? (last_u2_element() - 1) :
231342507Sarybchik                                        last_u2_element();
232342507Sarybchik      }
233342507Sarybchik    }
234342507Sarybchik  }
235342507Sarybchik}
236342507Sarybchik
237342507Sarybchik// Update the flags to indicate the presence of these optional fields.
238342507Sarybchikvoid ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
239342507Sarybchik  _flags = 0;
240342507Sarybchik  if (sizes->compressed_linenumber_size() > 0)
241342507Sarybchik    _flags |= _has_linenumber_table;
242342507Sarybchik  if (sizes->generic_signature_index() != 0)
243342507Sarybchik    _flags |= _has_generic_signature;
244342507Sarybchik  if (sizes->method_parameters_length() >= 0)
245342507Sarybchik    _flags |= _has_method_parameters;
246342507Sarybchik  if (sizes->checked_exceptions_length() > 0)
247342507Sarybchik    _flags |= _has_checked_exceptions;
248342507Sarybchik  if (sizes->exception_table_length() > 0)
249342507Sarybchik    _flags |= _has_exception_table;
250342507Sarybchik  if (sizes->localvariable_table_length() > 0)
251342507Sarybchik    _flags |= _has_localvariable_table;
252342507Sarybchik
253342507Sarybchik  // annotations, they are all pointer sized embedded objects so don't have
254342507Sarybchik  // a length embedded also.
255342507Sarybchik  if (sizes->method_annotations_length() > 0)
256342507Sarybchik    _flags |= _has_method_annotations;
257342507Sarybchik  if (sizes->parameter_annotations_length() > 0)
258342507Sarybchik    _flags |= _has_parameter_annotations;
259342507Sarybchik  if (sizes->type_annotations_length() > 0)
260342507Sarybchik    _flags |= _has_type_annotations;
261342507Sarybchik  if (sizes->default_annotations_length() > 0)
262342507Sarybchik    _flags |= _has_default_annotations;
263342507Sarybchik
264342507Sarybchik  // This code is extremely brittle and should possibly be revised.
265342507Sarybchik  // The *_length_addr functions walk backwards through the
266342507Sarybchik  // constMethod data, using each of the length indexes ahead of them,
267342507Sarybchik  // as well as the flags variable.  Therefore, the indexes must be
268342507Sarybchik  // initialized in reverse order, or else they will compute the wrong
269342507Sarybchik  // offsets.  Moving the initialization of _flags into a separate
270342507Sarybchik  // block solves *half* of the problem, but the following part will
271342507Sarybchik  // still break if the order is not exactly right.
272342507Sarybchik  //
273342507Sarybchik  // Also, the servicability agent needs to be informed anytime
274342507Sarybchik  // anything is added here.  It might be advisable to have some sort
275342507Sarybchik  // of indication of this inline.
276342507Sarybchik  if (sizes->generic_signature_index() != 0)
277342507Sarybchik    *(generic_signature_index_addr()) = sizes->generic_signature_index();
278342507Sarybchik  // New data should probably go here.
279342507Sarybchik  if (sizes->method_parameters_length() >= 0)
280342507Sarybchik    *(method_parameters_length_addr()) = sizes->method_parameters_length();
281342507Sarybchik  if (sizes->checked_exceptions_length() > 0)
282342507Sarybchik    *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
283342507Sarybchik  if (sizes->exception_table_length() > 0)
284293927Sarybchik    *(exception_table_length_addr()) = sizes->exception_table_length();
285227569Sphilip  if (sizes->localvariable_table_length() > 0)
286227569Sphilip    *(localvariable_table_length_addr()) = sizes->localvariable_table_length();
287227569Sphilip}
288227569Sphilip
289227569Sphilipint ConstMethod::method_parameters_length() const {
290227569Sphilip  return has_method_parameters() ? *(method_parameters_length_addr()) : -1;
291227569Sphilip}
292284555Sarybchik
293293927SarybchikMethodParametersElement* ConstMethod::method_parameters_start() const {
294227569Sphilip  u2* addr = method_parameters_length_addr();
295227569Sphilip  u2 length = *addr;
296227569Sphilip  addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
297284555Sarybchik  return (MethodParametersElement*) addr;
298342507Sarybchik}
299227569Sphilip
300227569Sphilip
301284555Sarybchikint ConstMethod::checked_exceptions_length() const {
302284555Sarybchik  return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
303284555Sarybchik}
304284555Sarybchik
305284555Sarybchik
306284555SarybchikCheckedExceptionElement* ConstMethod::checked_exceptions_start() const {
307284555Sarybchik  u2* addr = checked_exceptions_length_addr();
308284555Sarybchik  u2 length = *addr;
309284555Sarybchik  assert(length > 0, "should only be called if table is present");
310284555Sarybchik  addr -= length * sizeof(CheckedExceptionElement) / sizeof(u2);
311227569Sphilip  return (CheckedExceptionElement*) addr;
312227569Sphilip}
313284555Sarybchik
314284555Sarybchik
315227569Sphilipint ConstMethod::localvariable_table_length() const {
316227569Sphilip  return has_localvariable_table() ? *(localvariable_table_length_addr()) : 0;
317284555Sarybchik}
318284555Sarybchik
319227569Sphilip
320227569SphilipLocalVariableTableElement* ConstMethod::localvariable_table_start() const {
321284555Sarybchik  u2* addr = localvariable_table_length_addr();
322227569Sphilip  u2 length = *addr;
323227569Sphilip  assert(length > 0, "should only be called if table is present");
324284555Sarybchik  addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
325284555Sarybchik  return (LocalVariableTableElement*) addr;
326284555Sarybchik}
327227569Sphilip
328227569Sphilipint ConstMethod::exception_table_length() const {
329284555Sarybchik  return has_exception_handler() ? *(exception_table_length_addr()) : 0;
330227569Sphilip}
331284555Sarybchik
332227569SphilipExceptionTableElement* ConstMethod::exception_table_start() const {
333227569Sphilip  u2* addr = exception_table_length_addr();
334227569Sphilip  u2 length = *addr;
335227569Sphilip  assert(length > 0, "should only be called if table is present");
336227569Sphilip  addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
337284555Sarybchik  return (ExceptionTableElement*)addr;
338227569Sphilip}
339227569Sphilip
340227569SphilipAnnotationArray** ConstMethod::method_annotations_addr() const {
341227569Sphilip  assert(has_method_annotations(), "should only be called if method annotations are present");
342227569Sphilip  return (AnnotationArray**)constMethod_end() - 1;
343284555Sarybchik}
344284555Sarybchik
345227569SphilipAnnotationArray** ConstMethod::parameter_annotations_addr() const {
346227569Sphilip  assert(has_parameter_annotations(), "should only be called if method parameter annotations are present");
347227569Sphilip  int offset = 1;
348284555Sarybchik  if (has_method_annotations()) offset++;
349284555Sarybchik  return (AnnotationArray**)constMethod_end() - offset;
350227569Sphilip}
351227569Sphilip
352227569SphilipAnnotationArray** ConstMethod::type_annotations_addr() const {
353284555Sarybchik  assert(has_type_annotations(), "should only be called if method type annotations are present");
354284555Sarybchik  int offset = 1;
355227569Sphilip  if (has_method_annotations()) offset++;
356227569Sphilip  if (has_parameter_annotations()) offset++;
357227569Sphilip  return (AnnotationArray**)constMethod_end() - offset;
358227569Sphilip}
359227569Sphilip
360227569SphilipAnnotationArray** ConstMethod::default_annotations_addr() const {
361227569Sphilip  assert(has_default_annotations(), "should only be called if method default annotations are present");
362284555Sarybchik  int offset = 1;
363284555Sarybchik  if (has_method_annotations()) offset++;
364284555Sarybchik  if (has_parameter_annotations()) offset++;
365284555Sarybchik  if (has_type_annotations()) offset++;
366227569Sphilip  return (AnnotationArray**)constMethod_end() - offset;
367227569Sphilip}
368227569Sphilip
369284555Sarybchik// copy annotations from 'cm' to 'this'
370227569Sphilipvoid ConstMethod::copy_annotations_from(ConstMethod* cm) {
371227569Sphilip  if (cm->has_method_annotations()) {
372227569Sphilip    assert(has_method_annotations(), "should be allocated already");
373284555Sarybchik    set_method_annotations(cm->method_annotations());
374227569Sphilip  }
375227569Sphilip  if (cm->has_parameter_annotations()) {
376227569Sphilip    assert(has_parameter_annotations(), "should be allocated already");
377227569Sphilip    set_parameter_annotations(cm->parameter_annotations());
378227569Sphilip  }
379227569Sphilip  if (cm->has_type_annotations()) {
380227569Sphilip    assert(has_type_annotations(), "should be allocated already");
381227569Sphilip    set_type_annotations(cm->type_annotations());
382227569Sphilip  }
383227569Sphilip  if (cm->has_default_annotations()) {
384227569Sphilip    assert(has_default_annotations(), "should be allocated already");
385227569Sphilip    set_default_annotations(cm->default_annotations());
386227569Sphilip  }
387227569Sphilip}
388227569Sphilip
389227569Sphilip// Printing
390227569Sphilip
391227569Sphilipvoid ConstMethod::print_on(outputStream* st) const {
392293927Sarybchik  ResourceMark rm;
393227569Sphilip  assert(is_constMethod(), "must be constMethod");
394227569Sphilip  st->print_cr("%s", internal_name());
395227569Sphilip  st->print(" - method:       " INTPTR_FORMAT " ", p2i((address)method()));
396227569Sphilip  method()->print_value_on(st); st->cr();
397293927Sarybchik  if (has_stackmap_table()) {
398227569Sphilip    st->print(" - stackmap data:       ");
399227569Sphilip    stackmap_data()->print_value_on(st);
400227569Sphilip    st->cr();
401227569Sphilip  }
402293927Sarybchik}
403227569Sphilip
404227569Sphilip// Short version of printing ConstMethod* - just print the name of the
405227569Sphilip// method it belongs to.
406227569Sphilipvoid ConstMethod::print_value_on(outputStream* st) const {
407284555Sarybchik  assert(is_constMethod(), "must be constMethod");
408227569Sphilip  st->print(" const part of method " );
409284555Sarybchik  method()->print_value_on(st);
410227569Sphilip}
411227569Sphilip
412284555Sarybchik#if INCLUDE_SERVICES
413284555Sarybchik// Size Statistics
414284555Sarybchikvoid ConstMethod::collect_statistics(KlassSizeStats *sz) const {
415284555Sarybchik  int n1, n2, n3;
416284555Sarybchik  sz->_const_method_bytes += (n1 = sz->count(this));
417284555Sarybchik  sz->_bytecode_bytes     += (n2 = code_size());
418284555Sarybchik  sz->_stackmap_bytes     += (n3 = sz->count_array(stackmap_data()));
419227569Sphilip
420227569Sphilip  // Count method annotations
421227569Sphilip  int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
422227569Sphilip  if (has_method_annotations()) {
423227569Sphilip    sz->_methods_annotations_bytes += (a1 = sz->count_array(method_annotations()));
424227569Sphilip  }
425227569Sphilip  if (has_parameter_annotations()) {
426227569Sphilip    sz->_methods_parameter_annotations_bytes += (a2 = sz->count_array(parameter_annotations()));
427227569Sphilip  }
428227569Sphilip  if (has_type_annotations()) {
429227569Sphilip    sz->_methods_type_annotations_bytes += (a3 = sz->count_array(type_annotations()));
430227569Sphilip  }
431227569Sphilip  if (has_default_annotations()) {
432227569Sphilip    sz->_methods_default_annotations_bytes += (a4 = sz->count_array(default_annotations()));
433227569Sphilip  }
434227569Sphilip
435227569Sphilip  int size_annotations = a1 + a2 + a3 + a4;
436227569Sphilip
437227569Sphilip  sz->_method_all_bytes += n1 + n3 + size_annotations; // note: n2 is part of n3
438293927Sarybchik  sz->_ro_bytes += n1 + n3 + size_annotations;
439227569Sphilip}
440227569Sphilip#endif // INCLUDE_SERVICES
441227569Sphilip
442227569Sphilip// Verification
443227569Sphilip
444227569Sphilipvoid ConstMethod::verify_on(outputStream* st) {
445227569Sphilip  guarantee(is_constMethod(), "object must be constMethod");
446227569Sphilip
447227569Sphilip  // Verification can occur during oop construction before the method or
448227569Sphilip  // other fields have been initialized.
449227569Sphilip  guarantee(method()->is_method(), "should be method");
450227569Sphilip
451227569Sphilip  address m_end = (address)((intptr_t) this + size());
452227569Sphilip  address compressed_table_start = code_end();
453227569Sphilip  guarantee(compressed_table_start <= m_end, "invalid method layout");
454227569Sphilip  address compressed_table_end = compressed_table_start;
455227569Sphilip  // Verify line number table
456227569Sphilip  if (has_linenumber_table()) {
457227569Sphilip    CompressedLineNumberReadStream stream(compressed_linenumber_table());
458227569Sphilip    while (stream.read_pair()) {
459227569Sphilip      guarantee(stream.bci() >= 0 && stream.bci() <= code_size(), "invalid bci in line number table");
460227569Sphilip    }
461227569Sphilip    compressed_table_end += stream.position();
462227569Sphilip  }
463227569Sphilip  guarantee(compressed_table_end <= m_end, "invalid method layout");
464227569Sphilip  // Verify checked exceptions, exception table and local variable tables
465227569Sphilip  if (has_method_parameters()) {
466227569Sphilip    u2* addr = method_parameters_length_addr();
467227569Sphilip    guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
468227569Sphilip  }
469227569Sphilip  if (has_checked_exceptions()) {
470227569Sphilip    u2* addr = checked_exceptions_length_addr();
471227569Sphilip    guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
472227569Sphilip  }
473293927Sarybchik  if (has_exception_handler()) {
474227569Sphilip    u2* addr = exception_table_length_addr();
475227569Sphilip     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
476227569Sphilip  }
477293927Sarybchik  if (has_localvariable_table()) {
478227569Sphilip    u2* addr = localvariable_table_length_addr();
479227569Sphilip    guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
480227569Sphilip  }
481284555Sarybchik  // Check compressed_table_end relative to uncompressed_table_start
482284555Sarybchik  u2* uncompressed_table_start;
483227569Sphilip  if (has_localvariable_table()) {
484227569Sphilip    uncompressed_table_start = (u2*) localvariable_table_start();
485227569Sphilip  } else if (has_exception_handler()) {
486227569Sphilip    uncompressed_table_start = (u2*) exception_table_start();
487227569Sphilip  } else if (has_checked_exceptions()) {
488227569Sphilip      uncompressed_table_start = (u2*) checked_exceptions_start();
489227569Sphilip  } else if (has_method_parameters()) {
490227569Sphilip      uncompressed_table_start = (u2*) method_parameters_start();
491227569Sphilip  } else {
492227569Sphilip      uncompressed_table_start = (u2*) m_end;
493227569Sphilip  }
494227569Sphilip  int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
495227569Sphilip  int max_gap = align_object_size(1)*BytesPerWord;
496227569Sphilip  guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
497293954Sarybchik}
498293954Sarybchik