68 // ------------------------------------------------------------------ |
68 // ------------------------------------------------------------------ |
69 // ciField::ciField |
69 // ciField::ciField |
70 ciField::ciField(ciInstanceKlass* klass, int index) : |
70 ciField::ciField(ciInstanceKlass* klass, int index) : |
71 _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { |
71 _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { |
72 ASSERT_IN_VM; |
72 ASSERT_IN_VM; |
73 CompilerThread *thread = CompilerThread::current(); |
73 CompilerThread *THREAD = CompilerThread::current(); |
74 |
74 |
75 assert(ciObjectFactory::is_initialized(), "not a shared field"); |
75 assert(ciObjectFactory::is_initialized(), "not a shared field"); |
76 |
76 |
77 assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constant-pool"); |
77 assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constant-pool"); |
78 |
78 |
79 constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); |
79 constantPoolHandle cpool(THREAD, klass->get_instanceKlass()->constants()); |
80 |
80 |
81 // Get the field's name, signature, and type. |
81 // Get the field's name, signature, and type. |
82 Symbol* name = cpool->name_ref_at(index); |
82 Symbol* name = cpool->name_ref_at(index); |
83 _name = ciEnv::current(thread)->get_symbol(name); |
83 _name = ciEnv::current(THREAD)->get_symbol(name); |
84 |
84 |
85 int nt_index = cpool->name_and_type_ref_index_at(index); |
85 int nt_index = cpool->name_and_type_ref_index_at(index); |
86 int sig_index = cpool->signature_ref_index_at(nt_index); |
86 int sig_index = cpool->signature_ref_index_at(nt_index); |
87 Symbol* signature = cpool->symbol_at(sig_index); |
87 Symbol* signature = cpool->symbol_at(sig_index); |
88 _signature = ciEnv::current(thread)->get_symbol(signature); |
88 _signature = ciEnv::current(THREAD)->get_symbol(signature); |
89 |
89 |
90 BasicType field_type = FieldType::basic_type(signature); |
90 BasicType field_type = FieldType::basic_type(signature); |
91 |
91 |
92 // If the field is a pointer type, get the klass of the |
92 // If the field is a pointer type, get the klass of the |
93 // field. |
93 // field. |
94 if (field_type == T_OBJECT || field_type == T_ARRAY) { |
94 if (field_type == T_OBJECT || field_type == T_ARRAY) { |
95 bool ignore; |
95 bool ignore; |
96 // This is not really a class reference; the index always refers to the |
96 // This is not really a class reference; the index always refers to the |
97 // field's type signature, as a symbol. Linkage checks do not apply. |
97 // field's type signature, as a symbol. Linkage checks do not apply. |
98 _type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass); |
98 _type = ciEnv::current(THREAD)->get_klass_by_index(cpool, sig_index, ignore, klass); |
99 } else { |
99 } else { |
100 _type = ciType::make(field_type); |
100 _type = ciType::make(field_type); |
101 } |
101 } |
102 |
102 |
103 _name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name); |
103 _name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name); |
104 |
104 |
105 // Get the field's declared holder. |
105 // Get the field's declared holder. |
106 // |
106 // |
107 // Note: we actually create a ciInstanceKlass for this klass, |
107 // Note: we actually create a ciInstanceKlass for this klass, |
108 // even though we may not need to. |
108 // even though we may not need to. |
109 int holder_index = cpool->klass_ref_index_at(index); |
109 int holder_index = cpool->klass_ref_index_at(index); |
110 bool holder_is_accessible; |
110 bool holder_is_accessible; |
111 |
111 |
112 ciKlass* generic_declared_holder = ciEnv::current(thread)->get_klass_by_index(cpool, holder_index, |
112 ciKlass* generic_declared_holder = ciEnv::current(THREAD)->get_klass_by_index(cpool, holder_index, |
113 holder_is_accessible, |
113 holder_is_accessible, |
114 klass); |
114 klass); |
115 |
115 |
116 if (generic_declared_holder->is_array_klass()) { |
116 if (generic_declared_holder->is_array_klass()) { |
117 // If the declared holder of the field is an array class, assume that |
117 // If the declared holder of the field is an array class, assume that |
124 // have any fields. Therefore, the field is not looked up. Instead, |
124 // have any fields. Therefore, the field is not looked up. Instead, |
125 // the method returns partial information that will trigger special |
125 // the method returns partial information that will trigger special |
126 // handling in ciField::will_link and will result in a |
126 // handling in ciField::will_link and will result in a |
127 // java.lang.NoSuchFieldError exception being thrown by the compiled |
127 // java.lang.NoSuchFieldError exception being thrown by the compiled |
128 // code (the expected behavior in this case). |
128 // code (the expected behavior in this case). |
129 _holder = ciEnv::current(thread)->Object_klass(); |
129 _holder = ciEnv::current(THREAD)->Object_klass(); |
130 _offset = -1; |
130 _offset = -1; |
131 _is_constant = false; |
131 _is_constant = false; |
132 return; |
132 return; |
133 } |
133 } |
134 |
134 |
162 |
162 |
163 // Access check based on declared_holder. canonical_holder should not be used |
163 // Access check based on declared_holder. canonical_holder should not be used |
164 // to check access because it can erroneously succeed. If this check fails, |
164 // to check access because it can erroneously succeed. If this check fails, |
165 // propagate the declared holder to will_link() which in turn will bail out |
165 // propagate the declared holder to will_link() which in turn will bail out |
166 // compilation for this field access. |
166 // compilation for this field access. |
167 if (!Reflection::verify_field_access(klass->get_Klass(), declared_holder->get_Klass(), canonical_holder, field_desc.access_flags(), true)) { |
167 bool can_access = Reflection::verify_member_access(klass->get_Klass(), |
|
168 declared_holder->get_Klass(), |
|
169 canonical_holder, |
|
170 field_desc.access_flags(), |
|
171 true, false, THREAD); |
|
172 if (!can_access) { |
168 _holder = declared_holder; |
173 _holder = declared_holder; |
169 _offset = -1; |
174 _offset = -1; |
170 _is_constant = false; |
175 _is_constant = false; |
|
176 // It's possible the access check failed due to a nestmate access check |
|
177 // encountering an exception. We can't propagate the exception from here |
|
178 // so we have to clear it. If the access check happens again in a different |
|
179 // context then the exception will be thrown there. |
|
180 if (HAS_PENDING_EXCEPTION) { |
|
181 CLEAR_PENDING_EXCEPTION; |
|
182 } |
171 return; |
183 return; |
172 } |
184 } |
173 |
185 |
174 assert(canonical_holder == field_desc.field_holder(), "just checking"); |
186 assert(canonical_holder == field_desc.field_holder(), "just checking"); |
175 initialize_from(&field_desc); |
187 initialize_from(&field_desc); |