1/*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2009 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#include "precompiled.hpp"
27#include "ci/ciInstance.hpp"
28#include "ci/ciStreams.hpp"
29#include "shark/sharkBuilder.hpp"
30#include "shark/sharkConstant.hpp"
31#include "shark/sharkValue.hpp"
32
33using namespace llvm;
34
35SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) {
36  ciConstant constant = iter->get_constant();
37  ciType *type = NULL;
38  if (constant.basic_type() == T_OBJECT) {
39    ciEnv *env = ciEnv::current();
40
41    assert(constant.as_object()->klass() == env->String_klass()
42           || constant.as_object()->klass() == env->Class_klass()
43           || constant.as_object()->klass()->is_subtype_of(env->MethodType_klass())
44           || constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be");
45
46    type = constant.as_object()->klass();
47  }
48  return new SharkConstant(constant, type);
49}
50
51SharkConstant* SharkConstant::for_field(ciBytecodeStream *iter) {
52  bool will_link;
53  ciField *field = iter->get_field(will_link);
54  assert(will_link, "typeflow responsibility");
55
56  return new SharkConstant(field->constant_value(), field->type());
57}
58
59SharkConstant::SharkConstant(ciConstant constant, ciType *type) {
60  SharkValue *value = NULL;
61
62  switch (constant.basic_type()) {
63  case T_BOOLEAN:
64  case T_BYTE:
65  case T_CHAR:
66  case T_SHORT:
67  case T_INT:
68    value = SharkValue::jint_constant(constant.as_int());
69    break;
70
71  case T_LONG:
72    value = SharkValue::jlong_constant(constant.as_long());
73    break;
74
75  case T_FLOAT:
76    value = SharkValue::jfloat_constant(constant.as_float());
77    break;
78
79  case T_DOUBLE:
80    value = SharkValue::jdouble_constant(constant.as_double());
81    break;
82
83  case T_OBJECT:
84  case T_ARRAY:
85    break;
86
87  case T_ILLEGAL:
88    // out of memory
89    _is_loaded = false;
90    return;
91
92  default:
93    tty->print_cr("Unhandled type %s", type2name(constant.basic_type()));
94    ShouldNotReachHere();
95  }
96
97  // Handle primitive types.  We create SharkValues for these
98  // now; doing so doesn't emit any code, and it allows us to
99  // delegate a bunch of stuff to the SharkValue code.
100  if (value) {
101    _value       = value;
102    _is_loaded   = true;
103    _is_nonzero  = value->zero_checked();
104    _is_two_word = value->is_two_word();
105    return;
106  }
107
108  // Handle reference types.  This is tricky because some
109  // ciObjects are psuedo-objects that refer to oops which
110  // have yet to be created.  We need to spot the unloaded
111  // objects (which differ between ldc* and get*, thanks!)
112  ciObject *object = constant.as_object();
113  assert(type != NULL, "shouldn't be");
114
115  if ((! object->is_null_object()) && object->klass() == ciEnv::current()->Class_klass()) {
116    ciKlass *klass = object->klass();
117    if (! klass->is_loaded()) {
118      _is_loaded = false;
119      return;
120    }
121  }
122
123  if (object->is_null_object() || ! object->can_be_constant() || ! object->is_loaded()) {
124    _is_loaded = false;
125    return;
126  }
127
128  _value       = NULL;
129  _object      = object;
130  _type        = type;
131  _is_loaded   = true;
132  _is_nonzero  = true;
133  _is_two_word = false;
134}
135