ciArray.cpp revision 7864:6a5be7f00868
1/* 2 * Copyright (c) 1999, 2015, 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 "ci/ciArray.hpp" 27#include "ci/ciArrayKlass.hpp" 28#include "ci/ciConstant.hpp" 29#include "ci/ciKlass.hpp" 30#include "ci/ciUtilities.hpp" 31#include "oops/objArrayOop.inline.hpp" 32#include "oops/oop.inline.hpp" 33#include "oops/typeArrayOop.hpp" 34 35// ciArray 36// 37// This class represents an arrayOop in the HotSpot virtual 38// machine. 39static BasicType fixup_element_type(BasicType bt) { 40 if (bt == T_ARRAY) return T_OBJECT; 41 if (bt == T_BOOLEAN) return T_BYTE; 42 return bt; 43} 44 45ciConstant ciArray::element_value_impl(BasicType elembt, 46 arrayOop ary, 47 int index) { 48 if (ary == NULL) 49 return ciConstant(); 50 assert(ary->is_array(), ""); 51 if (index < 0 || index >= ary->length()) 52 return ciConstant(); 53 ArrayKlass* ak = (ArrayKlass*) ary->klass(); 54 BasicType abt = ak->element_type(); 55 if (fixup_element_type(elembt) != 56 fixup_element_type(abt)) 57 return ciConstant(); 58 switch (elembt) { 59 case T_ARRAY: 60 case T_OBJECT: 61 { 62 assert(ary->is_objArray(), ""); 63 objArrayOop objary = (objArrayOop) ary; 64 oop elem = objary->obj_at(index); 65 ciEnv* env = CURRENT_ENV; 66 ciObject* box = env->get_object(elem); 67 return ciConstant(T_OBJECT, box); 68 } 69 } 70 assert(ary->is_typeArray(), ""); 71 typeArrayOop tary = (typeArrayOop) ary; 72 jint value = 0; 73 switch (elembt) { 74 case T_LONG: return ciConstant(tary->long_at(index)); 75 case T_FLOAT: return ciConstant(tary->float_at(index)); 76 case T_DOUBLE: return ciConstant(tary->double_at(index)); 77 default: return ciConstant(); 78 case T_BYTE: value = tary->byte_at(index); break; 79 case T_BOOLEAN: value = tary->byte_at(index) & 1; break; 80 case T_SHORT: value = tary->short_at(index); break; 81 case T_CHAR: value = tary->char_at(index); break; 82 case T_INT: value = tary->int_at(index); break; 83 } 84 return ciConstant(elembt, value); 85} 86 87// ------------------------------------------------------------------ 88// ciArray::element_value 89// 90// Current value of an element. 91// Returns T_ILLEGAL if there is no element at the given index. 92ciConstant ciArray::element_value(int index) { 93 BasicType elembt = element_basic_type(); 94 GUARDED_VM_ENTRY( 95 return element_value_impl(elembt, get_arrayOop(), index); 96 ) 97} 98 99// ------------------------------------------------------------------ 100// ciArray::element_value_by_offset 101// 102// Current value of an element at the specified offset. 103// Returns T_ILLEGAL if there is no element at the given offset. 104ciConstant ciArray::element_value_by_offset(intptr_t element_offset) { 105 BasicType elembt = element_basic_type(); 106 intptr_t shift = exact_log2(type2aelembytes(elembt)); 107 intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); 108 intptr_t index = (element_offset - header) >> shift; 109 intptr_t offset = header + ((intptr_t)index << shift); 110 if (offset != element_offset || index != (jint)index) 111 return ciConstant(); 112 return element_value((jint) index); 113} 114 115// ------------------------------------------------------------------ 116// ciArray::print_impl 117// 118// Implementation of the print method. 119void ciArray::print_impl(outputStream* st) { 120 st->print(" length=%d type=", length()); 121 klass()->print(st); 122} 123