1.1 --- a/src/share/vm/ci/ciArray.cpp Mon Sep 09 19:53:28 2013 +0200 1.2 +++ b/src/share/vm/ci/ciArray.cpp Tue Sep 10 14:51:48 2013 -0700 1.3 @@ -24,13 +24,92 @@ 1.4 1.5 #include "precompiled.hpp" 1.6 #include "ci/ciArray.hpp" 1.7 +#include "ci/ciArrayKlass.hpp" 1.8 +#include "ci/ciConstant.hpp" 1.9 #include "ci/ciKlass.hpp" 1.10 #include "ci/ciUtilities.hpp" 1.11 +#include "oops/objArrayOop.hpp" 1.12 +#include "oops/typeArrayOop.hpp" 1.13 1.14 // ciArray 1.15 // 1.16 // This class represents an arrayOop in the HotSpot virtual 1.17 // machine. 1.18 +static BasicType fixup_element_type(BasicType bt) { 1.19 + if (bt == T_ARRAY) return T_OBJECT; 1.20 + if (bt == T_BOOLEAN) return T_BYTE; 1.21 + return bt; 1.22 +} 1.23 + 1.24 +ciConstant ciArray::element_value_impl(BasicType elembt, 1.25 + arrayOop ary, 1.26 + int index) { 1.27 + if (ary == NULL) 1.28 + return ciConstant(); 1.29 + assert(ary->is_array(), ""); 1.30 + if (index < 0 || index >= ary->length()) 1.31 + return ciConstant(); 1.32 + ArrayKlass* ak = (ArrayKlass*) ary->klass(); 1.33 + BasicType abt = ak->element_type(); 1.34 + if (fixup_element_type(elembt) != 1.35 + fixup_element_type(abt)) 1.36 + return ciConstant(); 1.37 + switch (elembt) { 1.38 + case T_ARRAY: 1.39 + case T_OBJECT: 1.40 + { 1.41 + assert(ary->is_objArray(), ""); 1.42 + objArrayOop objary = (objArrayOop) ary; 1.43 + oop elem = objary->obj_at(index); 1.44 + ciEnv* env = CURRENT_ENV; 1.45 + ciObject* box = env->get_object(elem); 1.46 + return ciConstant(T_OBJECT, box); 1.47 + } 1.48 + } 1.49 + assert(ary->is_typeArray(), ""); 1.50 + typeArrayOop tary = (typeArrayOop) ary; 1.51 + jint value = 0; 1.52 + switch (elembt) { 1.53 + case T_LONG: return ciConstant(tary->long_at(index)); 1.54 + case T_FLOAT: return ciConstant(tary->float_at(index)); 1.55 + case T_DOUBLE: return ciConstant(tary->double_at(index)); 1.56 + default: return ciConstant(); 1.57 + case T_BYTE: value = tary->byte_at(index); break; 1.58 + case T_BOOLEAN: value = tary->byte_at(index) & 1; break; 1.59 + case T_SHORT: value = tary->short_at(index); break; 1.60 + case T_CHAR: value = tary->char_at(index); break; 1.61 + case T_INT: value = tary->int_at(index); break; 1.62 + } 1.63 + return ciConstant(elembt, value); 1.64 +} 1.65 + 1.66 +// ------------------------------------------------------------------ 1.67 +// ciArray::element_value 1.68 +// 1.69 +// Current value of an element. 1.70 +// Returns T_ILLEGAL if there is no element at the given index. 1.71 +ciConstant ciArray::element_value(int index) { 1.72 + BasicType elembt = element_basic_type(); 1.73 + GUARDED_VM_ENTRY( 1.74 + return element_value_impl(elembt, get_arrayOop(), index); 1.75 + ) 1.76 +} 1.77 + 1.78 +// ------------------------------------------------------------------ 1.79 +// ciArray::element_value_by_offset 1.80 +// 1.81 +// Current value of an element at the specified offset. 1.82 +// Returns T_ILLEGAL if there is no element at the given offset. 1.83 +ciConstant ciArray::element_value_by_offset(intptr_t element_offset) { 1.84 + BasicType elembt = element_basic_type(); 1.85 + intptr_t shift = exact_log2(type2aelembytes(elembt)); 1.86 + intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); 1.87 + intptr_t index = (element_offset - header) >> shift; 1.88 + intptr_t offset = header + ((intptr_t)index << shift); 1.89 + if (offset != element_offset || index != (jint)index) 1.90 + return ciConstant(); 1.91 + return element_value((jint) index); 1.92 +} 1.93 1.94 // ------------------------------------------------------------------ 1.95 // ciArray::print_impl