ciArray.cpp revision 5776:de6a9e811145
157828Sjlemon/* 257828Sjlemon * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 357828Sjlemon * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 457828Sjlemon * 557828Sjlemon * This code is free software; you can redistribute it and/or modify it 657828Sjlemon * under the terms of the GNU General Public License version 2 only, as 757828Sjlemon * published by the Free Software Foundation. 857828Sjlemon * 957828Sjlemon * This code is distributed in the hope that it will be useful, but WITHOUT 1057828Sjlemon * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1157828Sjlemon * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1257828Sjlemon * version 2 for more details (a copy is included in the LICENSE file that 1357828Sjlemon * accompanied this code). 1457828Sjlemon * 1557828Sjlemon * You should have received a copy of the GNU General Public License version 1657828Sjlemon * 2 along with this work; if not, write to the Free Software Foundation, 1757828Sjlemon * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1857828Sjlemon * 1957828Sjlemon * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2057828Sjlemon * or visit www.oracle.com if you need additional information or have any 2157828Sjlemon * questions. 2257828Sjlemon * 2357828Sjlemon */ 2457828Sjlemon 2557828Sjlemon#include "precompiled.hpp" 2657828Sjlemon#include "ci/ciArray.hpp" 2757828Sjlemon#include "ci/ciArrayKlass.hpp" 2857828Sjlemon#include "ci/ciConstant.hpp" 2957828Sjlemon#include "ci/ciKlass.hpp" 3057828Sjlemon#include "ci/ciUtilities.hpp" 3157828Sjlemon#include "oops/objArrayOop.hpp" 3257828Sjlemon#include "oops/typeArrayOop.hpp" 3357828Sjlemon 3457828Sjlemon// ciArray 3560041Sphk// 3657828Sjlemon// This class represents an arrayOop in the HotSpot virtual 3757828Sjlemon// machine. 3857828Sjlemonstatic BasicType fixup_element_type(BasicType bt) { 3957828Sjlemon if (bt == T_ARRAY) return T_OBJECT; 4057828Sjlemon if (bt == T_BOOLEAN) return T_BYTE; 4157828Sjlemon return bt; 4257828Sjlemon} 4357828Sjlemon 4457828SjlemonciConstant ciArray::element_value_impl(BasicType elembt, 4557828Sjlemon arrayOop ary, 4657828Sjlemon int index) { 4757828Sjlemon if (ary == NULL) 4857828Sjlemon return ciConstant(); 4957828Sjlemon assert(ary->is_array(), ""); 5057828Sjlemon if (index < 0 || index >= ary->length()) 5157828Sjlemon return ciConstant(); 5257828Sjlemon ArrayKlass* ak = (ArrayKlass*) ary->klass(); 5357828Sjlemon BasicType abt = ak->element_type(); 5457828Sjlemon if (fixup_element_type(elembt) != 5557828Sjlemon fixup_element_type(abt)) 5657828Sjlemon return ciConstant(); 5757828Sjlemon switch (elembt) { 5857828Sjlemon case T_ARRAY: 5957828Sjlemon case T_OBJECT: 6057828Sjlemon { 6157828Sjlemon assert(ary->is_objArray(), ""); 6257828Sjlemon objArrayOop objary = (objArrayOop) ary; 6357828Sjlemon oop elem = objary->obj_at(index); 6457828Sjlemon ciEnv* env = CURRENT_ENV; 6557828Sjlemon ciObject* box = env->get_object(elem); 6657828Sjlemon return ciConstant(T_OBJECT, box); 6757828Sjlemon } 6857828Sjlemon } 6957828Sjlemon assert(ary->is_typeArray(), ""); 7057828Sjlemon typeArrayOop tary = (typeArrayOop) ary; 7157828Sjlemon jint value = 0; 7257828Sjlemon switch (elembt) { 7357828Sjlemon case T_LONG: return ciConstant(tary->long_at(index)); 7457828Sjlemon case T_FLOAT: return ciConstant(tary->float_at(index)); 7557828Sjlemon case T_DOUBLE: return ciConstant(tary->double_at(index)); 7657828Sjlemon default: return ciConstant(); 7757828Sjlemon case T_BYTE: value = tary->byte_at(index); break; 7857828Sjlemon case T_BOOLEAN: value = tary->byte_at(index) & 1; break; 7957828Sjlemon case T_SHORT: value = tary->short_at(index); break; 8057828Sjlemon case T_CHAR: value = tary->char_at(index); break; 8157828Sjlemon case T_INT: value = tary->int_at(index); break; 8257828Sjlemon } 8359209Smdodd return ciConstant(elembt, value); 8457828Sjlemon} 8557828Sjlemon 8657828Sjlemon// ------------------------------------------------------------------ 8757828Sjlemon// ciArray::element_value 8857828Sjlemon// 8957828Sjlemon// Current value of an element. 9057828Sjlemon// Returns T_ILLEGAL if there is no element at the given index. 9157828SjlemonciConstant ciArray::element_value(int index) { 9257828Sjlemon BasicType elembt = element_basic_type(); 9357828Sjlemon GUARDED_VM_ENTRY( 9457828Sjlemon return element_value_impl(elembt, get_arrayOop(), index); 9557828Sjlemon ) 9657828Sjlemon} 9757828Sjlemon 9857828Sjlemon// ------------------------------------------------------------------ 9957828Sjlemon// ciArray::element_value_by_offset 10057828Sjlemon// 10157828Sjlemon// Current value of an element at the specified offset. 10257828Sjlemon// Returns T_ILLEGAL if there is no element at the given offset. 10357828SjlemonciConstant ciArray::element_value_by_offset(intptr_t element_offset) { 10457828Sjlemon BasicType elembt = element_basic_type(); 10557828Sjlemon intptr_t shift = exact_log2(type2aelembytes(elembt)); 10657828Sjlemon intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); 10757828Sjlemon intptr_t index = (element_offset - header) >> shift; 10857828Sjlemon intptr_t offset = header + ((intptr_t)index << shift); 10957828Sjlemon if (offset != element_offset || index != (jint)index) 11057828Sjlemon return ciConstant(); 11157828Sjlemon return element_value((jint) index); 11257828Sjlemon} 11357828Sjlemon 11457828Sjlemon// ------------------------------------------------------------------ 11557828Sjlemon// ciArray::print_impl 11657828Sjlemon// 11757828Sjlemon// Implementation of the print method. 11857828Sjlemonvoid ciArray::print_impl(outputStream* st) { 11957828Sjlemon st->print(" length=%d type=", length()); 12057828Sjlemon klass()->print(st); 12157828Sjlemon} 12257828Sjlemon