1 /*
   2  * Copyright (c) 1997, 2010, 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/systemDictionary.hpp"
  27 #include "classfile/vmSymbols.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "memory/universe.inline.hpp"
  30 #include "oops/instanceKlass.hpp"
  31 #include "runtime/fieldDescriptor.hpp"
  32 #include "runtime/handles.inline.hpp"
  33 #include "runtime/signature.hpp"
  34 
  35 
  36 oop fieldDescriptor::loader() const {
  37   return instanceKlass::cast(_cp->pool_holder())->class_loader();
  38 }
  39 
  40 typeArrayOop fieldDescriptor::annotations() const {
  41   instanceKlass* ik = instanceKlass::cast(field_holder());
  42   objArrayOop md = ik->fields_annotations();
  43   if (md == NULL)
  44     return NULL;
  45   assert((index() % instanceKlass::next_offset) == 0, "");
  46   return typeArrayOop(md->obj_at(index() / instanceKlass::next_offset));
  47 }
  48 
  49 constantTag fieldDescriptor::initial_value_tag() const {
  50   return constants()->tag_at(_initial_value_index);
  51 }
  52 
  53 jint fieldDescriptor::int_initial_value() const {
  54   return constants()->int_at(_initial_value_index);
  55 }
  56 
  57 jlong fieldDescriptor::long_initial_value() const {
  58   return constants()->long_at(_initial_value_index);
  59 }
  60 
  61 jfloat fieldDescriptor::float_initial_value() const {
  62   return constants()->float_at(_initial_value_index);
  63 }
  64 
  65 jdouble fieldDescriptor::double_initial_value() const {
  66   return constants()->double_at(_initial_value_index);
  67 }
  68 
  69 oop fieldDescriptor::string_initial_value(TRAPS) const {
  70   return constants()->string_at(_initial_value_index, CHECK_0);
  71 }
  72 
  73 void fieldDescriptor::initialize(klassOop k, int index) {
  74   instanceKlass* ik = instanceKlass::cast(k);
  75   _cp = ik->constants();
  76   typeArrayOop fields = ik->fields();
  77 
  78   assert(fields->length() % instanceKlass::next_offset == 0, "Illegal size of field array");
  79   assert(fields->length() >= index + instanceKlass::next_offset, "Illegal size of field array");
  80 
  81   _access_flags.set_field_flags(fields->ushort_at(index + instanceKlass::access_flags_offset));
  82   _name_index = fields->ushort_at(index + instanceKlass::name_index_offset);
  83   _signature_index = fields->ushort_at(index + instanceKlass::signature_index_offset);
  84   _initial_value_index = fields->ushort_at(index + instanceKlass::initval_index_offset);
  85   guarantee(_name_index != 0 && _signature_index != 0, "bad constant pool index for fieldDescriptor");
  86   _offset = ik->offset_from_fields( index );
  87   _generic_signature_index = fields->ushort_at(index + instanceKlass::generic_signature_offset);
  88   _index = index;
  89 }
  90 
  91 #ifndef PRODUCT
  92 
  93 void fieldDescriptor::print_on(outputStream* st) const {
  94   _access_flags.print_on(st);
  95   constants()->symbol_at(_name_index)->print_value_on(st);
  96   st->print(" ");
  97   constants()->symbol_at(_signature_index)->print_value_on(st);
  98   st->print(" @%d ", offset());
  99   if (WizardMode && has_initial_value()) {
 100     st->print("(initval ");
 101     constantTag t = initial_value_tag();
 102     if (t.is_int()) {
 103       st->print("int %d)", int_initial_value());
 104     } else if (t.is_long()){
 105       st->print_jlong(long_initial_value());
 106     } else if (t.is_float()){
 107       st->print("float %f)", float_initial_value());
 108     } else if (t.is_double()){
 109       st->print("double %lf)", double_initial_value());
 110     }
 111   }
 112 }
 113 
 114 void fieldDescriptor::print_on_for(outputStream* st, oop obj) {
 115   print_on(st);
 116   BasicType ft = field_type();
 117   jint as_int = 0;
 118   switch (ft) {
 119     case T_BYTE:
 120       as_int = (jint)obj->byte_field(offset());
 121       st->print(" %d", obj->byte_field(offset()));
 122       break;
 123     case T_CHAR:
 124       as_int = (jint)obj->char_field(offset());
 125       {
 126         jchar c = obj->char_field(offset());
 127         as_int = c;
 128         st->print(" %c %d", isprint(c) ? c : ' ', c);
 129       }
 130       break;
 131     case T_DOUBLE:
 132       st->print(" %lf", obj->double_field(offset()));
 133       break;
 134     case T_FLOAT:
 135       as_int = obj->int_field(offset());
 136       st->print(" %f", obj->float_field(offset()));
 137       break;
 138     case T_INT:
 139       as_int = obj->int_field(offset());
 140       st->print(" %d", obj->int_field(offset()));
 141       break;
 142     case T_LONG:
 143       st->print(" ");
 144       st->print_jlong(obj->long_field(offset()));
 145       break;
 146     case T_SHORT:
 147       as_int = obj->short_field(offset());
 148       st->print(" %d", obj->short_field(offset()));
 149       break;
 150     case T_BOOLEAN:
 151       as_int = obj->bool_field(offset());
 152       st->print(" %s", obj->bool_field(offset()) ? "true" : "false");
 153       break;
 154     case T_ARRAY:
 155       st->print(" ");
 156       NOT_LP64(as_int = obj->int_field(offset()));
 157       obj->obj_field(offset())->print_value_on(st);
 158       break;
 159     case T_OBJECT:
 160       st->print(" ");
 161       NOT_LP64(as_int = obj->int_field(offset()));
 162       obj->obj_field(offset())->print_value_on(st);
 163       break;
 164     default:
 165       ShouldNotReachHere();
 166       break;
 167   }
 168   // Print a hint as to the underlying integer representation. This can be wrong for
 169   // pointers on an LP64 machine
 170   if (ft == T_LONG || ft == T_DOUBLE LP64_ONLY(|| !is_java_primitive(ft)) ) {
 171     st->print(" (%x %x)", obj->int_field(offset()), obj->int_field(offset()+sizeof(jint)));
 172   } else if (as_int < 0 || as_int > 9) {
 173     st->print(" (%x)", as_int);
 174   }
 175 }
 176 
 177 #endif /* PRODUCT */