ciInstance.cpp revision 3602:da91efe96a93
17011SN/A/*
27011SN/A * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
37011SN/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47011SN/A *
57011SN/A * This code is free software; you can redistribute it and/or modify it
67011SN/A * under the terms of the GNU General Public License version 2 only, as
77011SN/A * published by the Free Software Foundation.
87011SN/A *
97011SN/A * This code is distributed in the hope that it will be useful, but WITHOUT
107011SN/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
117011SN/A * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
127011SN/A * version 2 for more details (a copy is included in the LICENSE file that
137011SN/A * accompanied this code).
147011SN/A *
157011SN/A * You should have received a copy of the GNU General Public License version
167011SN/A * 2 along with this work; if not, write to the Free Software Foundation,
177011SN/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
187011SN/A *
197011SN/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
207011SN/A * or visit www.oracle.com if you need additional information or have any
217011SN/A * questions.
227011SN/A *
237011SN/A */
247011SN/A
257011SN/A#include "precompiled.hpp"
267011SN/A#include "ci/ciConstant.hpp"
277011SN/A#include "ci/ciField.hpp"
287011SN/A#include "ci/ciInstance.hpp"
297011SN/A#include "ci/ciInstanceKlass.hpp"
307011SN/A#include "ci/ciUtilities.hpp"
317651SN/A#include "classfile/systemDictionary.hpp"
327011SN/A#include "oops/oop.inline.hpp"
337011SN/A
347011SN/A// ciInstance
359091SN/A//
367011SN/A// This class represents an instanceOop in the HotSpot virtual
377011SN/A// machine.
387011SN/A
397011SN/A// ------------------------------------------------------------------
407011SN/A// ciObject::java_mirror_type
417011SN/AciType* ciInstance::java_mirror_type() {
427011SN/A  VM_ENTRY_MARK;
437011SN/A  oop m = get_oop();
447011SN/A  // Return NULL if it is not java.lang.Class.
457011SN/A  if (m == NULL || m->klass() != SystemDictionary::Class_klass()) {
467011SN/A    return NULL;
477011SN/A  }
487011SN/A  // Return either a primitive type or a klass.
497011SN/A  if (java_lang_Class::is_primitive(m)) {
507011SN/A    return ciType::make(java_lang_Class::primitive_type(m));
517011SN/A  } else {
527011SN/A    Klass* k = java_lang_Class::as_Klass(m);
537011SN/A    assert(k != NULL, "");
547011SN/A    return CURRENT_THREAD_ENV->get_klass(k);
557011SN/A  }
567011SN/A}
577011SN/A
587011SN/A// ------------------------------------------------------------------
597011SN/A// ciInstance::field_value
607011SN/A//
617011SN/A// Constant value of a field.
627011SN/AciConstant ciInstance::field_value(ciField* field) {
637011SN/A  assert(is_loaded() &&
647011SN/A         field->holder()->is_loaded() &&
657011SN/A         klass()->is_subclass_of(field->holder()),
667011SN/A         "invalid access");
677011SN/A  VM_ENTRY_MARK;
687011SN/A  ciConstant result;
697011SN/A  Handle obj = get_oop();
707011SN/A  assert(!obj.is_null(), "bad oop");
717011SN/A  BasicType field_btype = field->type()->basic_type();
727011SN/A  int offset = field->offset();
737011SN/A
747011SN/A  switch(field_btype) {
757011SN/A  case T_BYTE:
767011SN/A    return ciConstant(field_btype, obj->byte_field(offset));
777011SN/A    break;
787011SN/A  case T_CHAR:
797011SN/A    return ciConstant(field_btype, obj->char_field(offset));
807011SN/A    break;
817011SN/A  case T_SHORT:
827011SN/A    return ciConstant(field_btype, obj->short_field(offset));
837011SN/A    break;
847011SN/A  case T_BOOLEAN:
857011SN/A    return ciConstant(field_btype, obj->bool_field(offset));
867011SN/A    break;
877011SN/A  case T_INT:
887011SN/A    return ciConstant(field_btype, obj->int_field(offset));
897011SN/A    break;
907011SN/A  case T_FLOAT:
917011SN/A    return ciConstant(obj->float_field(offset));
927011SN/A    break;
937011SN/A  case T_DOUBLE:
947011SN/A    return ciConstant(obj->double_field(offset));
957011SN/A    break;
967011SN/A  case T_LONG:
977011SN/A    return ciConstant(obj->long_field(offset));
987011SN/A    break;
997011SN/A  case T_OBJECT:
1007011SN/A  case T_ARRAY:
1017011SN/A    {
1027011SN/A      oop o = obj->obj_field(offset);
1037011SN/A
1047011SN/A      // A field will be "constant" if it is known always to be
1057011SN/A      // a non-null reference to an instance of a particular class,
1067011SN/A      // or to a particular array.  This can happen even if the instance
1077011SN/A      // or array is not perm.  In such a case, an "unloaded" ciArray
1087011SN/A      // or ciInstance is created.  The compiler may be able to use
1097011SN/A      // information about the object's class (which is exact) or length.
1107011SN/A
1117011SN/A      if (o == NULL) {
1127011SN/A        return ciConstant(field_btype, ciNullObject::make());
1137011SN/A      } else {
1147011SN/A        return ciConstant(field_btype, CURRENT_ENV->get_object(o));
1157011SN/A      }
1167011SN/A    }
1177011SN/A  }
1187011SN/A  ShouldNotReachHere();
1197011SN/A  // to shut up the compiler
1207011SN/A  return ciConstant();
1217011SN/A}
1227011SN/A
1237011SN/A// ------------------------------------------------------------------
1247011SN/A// ciInstance::field_value_by_offset
1257011SN/A//
1267011SN/A// Constant value of a field at the specified offset.
1277011SN/AciConstant ciInstance::field_value_by_offset(int field_offset) {
1287011SN/A  ciInstanceKlass* ik = klass()->as_instance_klass();
1297011SN/A  ciField* field = ik->get_field_by_offset(field_offset, false);
1307011SN/A  return field_value(field);
1317011SN/A}
1327011SN/A
13312745Smartin// ------------------------------------------------------------------
1347011SN/A// ciInstance::print_impl
1357011SN/A//
1367011SN/A// Implementation of the print method.
1377011SN/Avoid ciInstance::print_impl(outputStream* st) {
1387011SN/A  st->print(" type=");
1397011SN/A  klass()->print(st);
1407011SN/A}
1417011SN/A
1427011SN/A
1437011SN/AciKlass* ciInstance::java_lang_Class_klass() {
1447011SN/A  VM_ENTRY_MARK;
1457011SN/A  return CURRENT_ENV->get_metadata(java_lang_Class::as_Klass(get_oop()))->as_klass();
1467011SN/A}
1477011SN/A