annotations.cpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "classfile/classLoaderData.hpp"
27#include "memory/metadataFactory.hpp"
28#include "memory/oopFactory.hpp"
29#include "oops/annotations.hpp"
30#include "oops/instanceKlass.hpp"
31#include "utilities/ostream.hpp"
32
33// Allocate annotations in metadata area
34Annotations* Annotations::allocate(ClassLoaderData* loader_data, TRAPS) {
35  return new (loader_data, size(), true, THREAD) Annotations();
36}
37
38Annotations* Annotations::allocate(ClassLoaderData* loader_data,
39                                   Array<AnnotationArray*>* fa,
40                                   Array<AnnotationArray*>* ma,
41                                   Array<AnnotationArray*>* mpa,
42                                   Array<AnnotationArray*>* mda, TRAPS) {
43  return new (loader_data, size(), true, THREAD) Annotations(fa, ma, mpa, mda);
44}
45
46// helper
47static void free_contents(ClassLoaderData* loader_data, Array<AnnotationArray*>* p) {
48  if (p != NULL) {
49    for (int i = 0; i < p->length(); i++) {
50      MetadataFactory::free_array<u1>(loader_data, p->at(i));
51    }
52    MetadataFactory::free_array<AnnotationArray*>(loader_data, p);
53  }
54}
55
56void Annotations::deallocate_contents(ClassLoaderData* loader_data) {
57  if (class_annotations() != NULL) {
58    MetadataFactory::free_array<u1>(loader_data, class_annotations());
59  }
60  free_contents(loader_data, fields_annotations());
61  free_contents(loader_data, methods_annotations());
62  free_contents(loader_data, methods_parameter_annotations());
63  free_contents(loader_data, methods_default_annotations());
64}
65
66// Set the annotation at 'idnum' to 'anno'.
67// We don't want to create or extend the array if 'anno' is NULL, since that is the
68// default value.  However, if the array exists and is long enough, we must set NULL values.
69void Annotations::set_methods_annotations_of(instanceKlassHandle ik,
70                                             int idnum, AnnotationArray* anno,
71                                             Array<AnnotationArray*>** md_p,
72                                             TRAPS) {
73  Array<AnnotationArray*>* md = *md_p;
74  if (md != NULL && md->length() > idnum) {
75    md->at_put(idnum, anno);
76  } else if (anno != NULL) {
77    // create the array
78    int length = MAX2(idnum+1, (int)ik->idnum_allocated_count());
79    md = MetadataFactory::new_array<AnnotationArray*>(ik->class_loader_data(), length, CHECK);
80    if (*md_p != NULL) {
81      // copy the existing entries
82      for (int index = 0; index < (*md_p)->length(); index++) {
83        md->at_put(index, (*md_p)->at(index));
84      }
85    }
86    set_annotations(md, md_p);
87    md->at_put(idnum, anno);
88  } // if no array and idnum isn't included there is nothing to do
89}
90
91// Keep created annotations in a global growable array (should be hashtable)
92// need to add, search, delete when class is unloaded.
93// Does it need a lock?  yes.  This sucks.
94
95// Copy annotations to JVM call or reflection to the java heap.
96typeArrayOop Annotations::make_java_array(AnnotationArray* annotations, TRAPS) {
97  if (annotations != NULL) {
98    int length = annotations->length();
99    typeArrayOop copy = oopFactory::new_byteArray(length, CHECK_NULL);
100    for (int i = 0; i< length; i++) {
101      copy->byte_at_put(i, annotations->at(i));
102    }
103    return copy;
104  } else {
105    return NULL;
106  }
107}
108
109
110void Annotations::print_value_on(outputStream* st) const {
111  st->print("Anotations(" INTPTR_FORMAT ")", this);
112}
113
114#define BULLET  " - "
115
116#ifndef PRODUCT
117void Annotations::print_on(outputStream* st) const {
118  st->print(BULLET"class_annotations            "); class_annotations()->print_value_on(st);
119  st->print(BULLET"fields_annotations           "); fields_annotations()->print_value_on(st);
120  st->print(BULLET"methods_annotations          "); methods_annotations()->print_value_on(st);
121  st->print(BULLET"methods_parameter_annotations"); methods_parameter_annotations()->print_value_on(st);
122  st->print(BULLET"methods_default_annotations  "); methods_default_annotations()->print_value_on(st);
123}
124#endif // PRODUCT
125