annotations.cpp revision 3602:da91efe96a93
1254721Semaste/*
2254721Semaste * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3254721Semaste * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4254721Semaste *
5254721Semaste * This code is free software; you can redistribute it and/or modify it
6254721Semaste * under the terms of the GNU General Public License version 2 only, as
7254721Semaste * published by the Free Software Foundation.
8254721Semaste *
9254721Semaste * This code is distributed in the hope that it will be useful, but WITHOUT
10254721Semaste * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11254721Semaste * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12254721Semaste * version 2 for more details (a copy is included in the LICENSE file that
13254721Semaste * accompanied this code).
14254721Semaste *
15254721Semaste * You should have received a copy of the GNU General Public License version
16254721Semaste * 2 along with this work; if not, write to the Free Software Foundation,
17254721Semaste * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18254721Semaste *
19254721Semaste * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20254721Semaste * or visit www.oracle.com if you need additional information or have any
21254721Semaste * questions.
22254721Semaste *
23254721Semaste */
24254721Semaste
25254721Semaste#include "precompiled.hpp"
26254721Semaste#include "classfile/classLoaderData.hpp"
27254721Semaste#include "memory/metadataFactory.hpp"
28254721Semaste#include "memory/oopFactory.hpp"
29254721Semaste#include "oops/annotations.hpp"
30254721Semaste#include "oops/instanceKlass.hpp"
31254721Semaste#include "utilities/ostream.hpp"
32254721Semaste
33254721Semaste// Allocate annotations in metadata area
34254721SemasteAnnotations* Annotations::allocate(ClassLoaderData* loader_data, TRAPS) {
35254721Semaste  return new (loader_data, size(), true, THREAD) Annotations();
36254721Semaste}
37254721Semaste
38254721SemasteAnnotations* Annotations::allocate(ClassLoaderData* loader_data,
39254721Semaste                                   Array<AnnotationArray*>* fa,
40254721Semaste                                   Array<AnnotationArray*>* ma,
41254721Semaste                                   Array<AnnotationArray*>* mpa,
42254721Semaste                                   Array<AnnotationArray*>* mda, TRAPS) {
43254721Semaste  return new (loader_data, size(), true, THREAD) Annotations(fa, ma, mpa, mda);
44254721Semaste}
45254721Semaste
46254721Semaste// helper
47254721Semastestatic void free_contents(ClassLoaderData* loader_data, Array<AnnotationArray*>* p) {
48254721Semaste  if (p != NULL) {
49254721Semaste    for (int i = 0; i < p->length(); i++) {
50254721Semaste      MetadataFactory::free_array<u1>(loader_data, p->at(i));
51254721Semaste    }
52254721Semaste    MetadataFactory::free_array<AnnotationArray*>(loader_data, p);
53254721Semaste  }
54254721Semaste}
55254721Semaste
56254721Semastevoid Annotations::deallocate_contents(ClassLoaderData* loader_data) {
57254721Semaste  if (class_annotations() != NULL) {
58254721Semaste    MetadataFactory::free_array<u1>(loader_data, class_annotations());
59254721Semaste  }
60254721Semaste  free_contents(loader_data, fields_annotations());
61254721Semaste  free_contents(loader_data, methods_annotations());
62254721Semaste  free_contents(loader_data, methods_parameter_annotations());
63254721Semaste  free_contents(loader_data, methods_default_annotations());
64254721Semaste}
65254721Semaste
66254721Semaste// Set the annotation at 'idnum' to 'anno'.
67254721Semaste// We don't want to create or extend the array if 'anno' is NULL, since that is the
68254721Semaste// default value.  However, if the array exists and is long enough, we must set NULL values.
69254721Semastevoid Annotations::set_methods_annotations_of(instanceKlassHandle ik,
70254721Semaste                                             int idnum, AnnotationArray* anno,
71254721Semaste                                             Array<AnnotationArray*>** md_p,
72254721Semaste                                             TRAPS) {
73254721Semaste  Array<AnnotationArray*>* md = *md_p;
74254721Semaste  if (md != NULL && md->length() > idnum) {
75254721Semaste    md->at_put(idnum, anno);
76254721Semaste  } else if (anno != NULL) {
77254721Semaste    // create the array
78254721Semaste    int length = MAX2(idnum+1, (int)ik->idnum_allocated_count());
79254721Semaste    md = MetadataFactory::new_array<AnnotationArray*>(ik->class_loader_data(), length, CHECK);
80254721Semaste    if (*md_p != NULL) {
81254721Semaste      // copy the existing entries
82254721Semaste      for (int index = 0; index < (*md_p)->length(); index++) {
83254721Semaste        md->at_put(index, (*md_p)->at(index));
84254721Semaste      }
85254721Semaste    }
86254721Semaste    set_annotations(md, md_p);
87254721Semaste    md->at_put(idnum, anno);
88254721Semaste  } // if no array and idnum isn't included there is nothing to do
89254721Semaste}
90254721Semaste
91254721Semaste// Keep created annotations in a global growable array (should be hashtable)
92254721Semaste// need to add, search, delete when class is unloaded.
93254721Semaste// Does it need a lock?  yes.  This sucks.
94254721Semaste
95254721Semaste// Copy annotations to JVM call or reflection to the java heap.
96254721SemastetypeArrayOop Annotations::make_java_array(AnnotationArray* annotations, TRAPS) {
97254721Semaste  if (annotations != NULL) {
98254721Semaste    int length = annotations->length();
99254721Semaste    typeArrayOop copy = oopFactory::new_byteArray(length, CHECK_NULL);
100254721Semaste    for (int i = 0; i< length; i++) {
101254721Semaste      copy->byte_at_put(i, annotations->at(i));
102254721Semaste    }
103254721Semaste    return copy;
104254721Semaste  } else {
105254721Semaste    return NULL;
106254721Semaste  }
107254721Semaste}
108254721Semaste
109254721Semaste
110254721Semastevoid Annotations::print_value_on(outputStream* st) const {
111254721Semaste  st->print("Anotations(" INTPTR_FORMAT ")", this);
112254721Semaste}
113254721Semaste
114254721Semaste#define BULLET  " - "
115254721Semaste
116254721Semaste#ifndef PRODUCT
117254721Semastevoid Annotations::print_on(outputStream* st) const {
118254721Semaste  st->print(BULLET"class_annotations            "); class_annotations()->print_value_on(st);
119254721Semaste  st->print(BULLET"fields_annotations           "); fields_annotations()->print_value_on(st);
120254721Semaste  st->print(BULLET"methods_annotations          "); methods_annotations()->print_value_on(st);
121254721Semaste  st->print(BULLET"methods_parameter_annotations"); methods_parameter_annotations()->print_value_on(st);
122254721Semaste  st->print(BULLET"methods_default_annotations  "); methods_default_annotations()->print_value_on(st);
123254721Semaste}
124254721Semaste#endif // PRODUCT
125254721Semaste