void ciField::initialize_from(fieldDescriptor* fd) { // Get the flags, offset, and canonical holder of the field. _flags = ciFlags(fd->access_flags()); _offset = fd->offset(); _holder = CURRENT_ENV->get_object(fd->field_holder())->as_instance_klass(); // Check to see if the field is constant. if (_holder->is_initialized() && this->is_final()) { if (!this->is_static()) { // A field can be constant if it's a final static field or if // it's a final non-static field of a trusted class (classes in // java.lang.invoke and sun.invoke packages and subpackages). if (trust_final_non_static_fields(_holder)) { _is_constant = true; return; } _is_constant = false; return; } // This field just may be constant. The only cases where it will // not be constant are: // // 1. The field holds a non-perm-space oop. The field is, strictly // speaking, constant but we cannot embed non-perm-space oops into // generated code. For the time being we need to consider the // field to be not constant. // 2. The field is a *special* static&final field whose value // may change. The three examples are java.lang.System.in, // java.lang.System.out, and java.lang.System.err. KlassHandle k = _holder->get_klassOop(); assert( SystemDictionary::System_klass() != NULL, "Check once per vm"); if( k() == SystemDictionary::System_klass() ) { // Check offsets for case 2: System.in, System.out, or System.err if( _offset == java_lang_System::in_offset_in_bytes() || _offset == java_lang_System::out_offset_in_bytes() || _offset == java_lang_System::err_offset_in_bytes() ) { _is_constant = false; return; } } Handle mirror = k->java_mirror(); _is_constant = true; switch(type()->basic_type()) { case T_BYTE: _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); break; case T_CHAR: _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset)); break; case T_SHORT: _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset)); break; case T_BOOLEAN: _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset)); break; case T_INT: _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset)); break; case T_FLOAT: _constant_value = ciConstant(mirror->float_field(_offset)); break; case T_DOUBLE: _constant_value = ciConstant(mirror->double_field(_offset)); break; case T_LONG: _constant_value = ciConstant(mirror->long_field(_offset)); break; case T_OBJECT: case T_ARRAY: { oop o = mirror->obj_field(_offset); // A field will be "constant" if it is known always to be // a non-null reference to an instance of a particular class, // or to a particular array. This can happen even if the instance // or array is not perm. In such a case, an "unloaded" ciArray // or ciInstance is created. The compiler may be able to use // information about the object's class (which is exact) or length. if (o == NULL) { _constant_value = ciConstant(type()->basic_type(), ciNullObject::make()); } else { _constant_value = ciConstant(type()->basic_type(), CURRENT_ENV->get_object(o)); assert(_constant_value.as_object() == CURRENT_ENV->get_object(o), "check interning"); } } } } else { _is_constant = false; } }