Mercurial > hg > truffle
comparison src/share/vm/opto/parse3.cpp @ 12190:edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
Reviewed-by: rbackman, twisti, kvn
Contributed-by: john.r.rose@oracle.com, vladimir.x.ivanov@oracle.com
author | vlivanov |
---|---|
date | Tue, 10 Sep 2013 14:51:48 -0700 |
parents | fcf521c3fbc6 |
children | 5ec7dace41a6 2113136690bc |
comparison
equal
deleted
inserted
replaced
12188:cd16d587b0fa | 12190:edb5ab0f3fe5 |
---|---|
145 | 145 |
146 | 146 |
147 void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { | 147 void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { |
148 // Does this field have a constant value? If so, just push the value. | 148 // Does this field have a constant value? If so, just push the value. |
149 if (field->is_constant()) { | 149 if (field->is_constant()) { |
150 // final field | 150 // final or stable field |
151 const Type* stable_type = NULL; | |
152 if (FoldStableValues && field->is_stable()) { | |
153 stable_type = Type::get_const_type(field->type()); | |
154 if (field->type()->is_array_klass()) { | |
155 int stable_dimension = field->type()->as_array_klass()->dimension(); | |
156 stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension); | |
157 } | |
158 } | |
151 if (field->is_static()) { | 159 if (field->is_static()) { |
152 // final static field | 160 // final static field |
153 if (C->eliminate_boxing()) { | 161 if (C->eliminate_boxing()) { |
154 // The pointers in the autobox arrays are always non-null. | 162 // The pointers in the autobox arrays are always non-null. |
155 ciSymbol* klass_name = field->holder()->name(); | 163 ciSymbol* klass_name = field->holder()->name(); |
165 if (push_constant(field->constant_value(), require_const, autobox_cache)) { | 173 if (push_constant(field->constant_value(), require_const, autobox_cache)) { |
166 return; | 174 return; |
167 } | 175 } |
168 } | 176 } |
169 } | 177 } |
170 if (push_constant(field->constant_value())) | 178 if (push_constant(field->constant_value(), false, false, stable_type)) |
171 return; | 179 return; |
172 } | 180 } else { |
173 else { | 181 // final or stable non-static field |
174 // final non-static field | |
175 // Treat final non-static fields of trusted classes (classes in | 182 // Treat final non-static fields of trusted classes (classes in |
176 // java.lang.invoke and sun.invoke packages and subpackages) as | 183 // java.lang.invoke and sun.invoke packages and subpackages) as |
177 // compile time constants. | 184 // compile time constants. |
178 if (obj->is_Con()) { | 185 if (obj->is_Con()) { |
179 const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); | 186 const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); |
180 ciObject* constant_oop = oop_ptr->const_oop(); | 187 ciObject* constant_oop = oop_ptr->const_oop(); |
181 ciConstant constant = field->constant_value_of(constant_oop); | 188 ciConstant constant = field->constant_value_of(constant_oop); |
182 if (push_constant(constant, true)) | 189 if (FoldStableValues && field->is_stable() && constant.is_null_or_zero()) { |
183 return; | 190 // fall through to field load; the field is not yet initialized |
191 } else { | |
192 if (push_constant(constant, true, false, stable_type)) | |
193 return; | |
194 } | |
184 } | 195 } |
185 } | 196 } |
186 } | 197 } |
187 | 198 |
188 ciType* field_klass = field->type(); | 199 ciType* field_klass = field->type(); |
299 | 310 |
300 // If the field is final, the rules of Java say we are in <init> or <clinit>. | 311 // If the field is final, the rules of Java say we are in <init> or <clinit>. |
301 // Note the presence of writes to final non-static fields, so that we | 312 // Note the presence of writes to final non-static fields, so that we |
302 // can insert a memory barrier later on to keep the writes from floating | 313 // can insert a memory barrier later on to keep the writes from floating |
303 // out of the constructor. | 314 // out of the constructor. |
304 if (is_field && field->is_final()) { | 315 // Any method can write a @Stable field; insert memory barriers after those also. |
316 if (is_field && (field->is_final() || field->is_stable())) { | |
305 set_wrote_final(true); | 317 set_wrote_final(true); |
306 // Preserve allocation ptr to create precedent edge to it in membar | 318 // Preserve allocation ptr to create precedent edge to it in membar |
307 // generated on exit from constructor. | 319 // generated on exit from constructor. |
308 if (C->eliminate_boxing() && | 320 if (C->eliminate_boxing() && |
309 adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() && | 321 adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() && |
312 } | 324 } |
313 } | 325 } |
314 } | 326 } |
315 | 327 |
316 | 328 |
317 bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) { | 329 |
330 bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache, const Type* stable_type) { | |
331 const Type* con_type = Type::make_from_constant(constant, require_constant, is_autobox_cache); | |
318 switch (constant.basic_type()) { | 332 switch (constant.basic_type()) { |
319 case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break; | |
320 case T_INT: push( intcon(constant.as_int()) ); break; | |
321 case T_CHAR: push( intcon(constant.as_char()) ); break; | |
322 case T_BYTE: push( intcon(constant.as_byte()) ); break; | |
323 case T_SHORT: push( intcon(constant.as_short()) ); break; | |
324 case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break; | |
325 case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break; | |
326 case T_LONG: push_pair( longcon(constant.as_long()) ); break; | |
327 case T_ARRAY: | 333 case T_ARRAY: |
328 case T_OBJECT: { | 334 case T_OBJECT: |
329 // cases: | 335 // cases: |
330 // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) | 336 // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) |
331 // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) | 337 // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) |
332 // An oop is not scavengable if it is in the perm gen. | 338 // An oop is not scavengable if it is in the perm gen. |
333 ciObject* oop_constant = constant.as_object(); | 339 if (stable_type != NULL && con_type != NULL && con_type->isa_oopptr()) |
334 if (oop_constant->is_null_object()) { | 340 con_type = con_type->join(stable_type); |
335 push( zerocon(T_OBJECT) ); | 341 break; |
336 break; | 342 |
337 } else if (require_constant || oop_constant->should_be_constant()) { | 343 case T_ILLEGAL: |
338 push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) ); | |
339 break; | |
340 } else { | |
341 // we cannot inline the oop, but we can use it later to narrow a type | |
342 return false; | |
343 } | |
344 } | |
345 case T_ILLEGAL: { | |
346 // Invalid ciConstant returned due to OutOfMemoryError in the CI | 344 // Invalid ciConstant returned due to OutOfMemoryError in the CI |
347 assert(C->env()->failing(), "otherwise should not see this"); | 345 assert(C->env()->failing(), "otherwise should not see this"); |
348 // These always occur because of object types; we are going to | 346 // These always occur because of object types; we are going to |
349 // bail out anyway, so make the stack depths match up | 347 // bail out anyway, so make the stack depths match up |
350 push( zerocon(T_OBJECT) ); | 348 push( zerocon(T_OBJECT) ); |
351 return false; | 349 return false; |
352 } | 350 } |
353 default: | 351 |
354 ShouldNotReachHere(); | 352 if (con_type == NULL) |
353 // we cannot inline the oop, but we can use it later to narrow a type | |
355 return false; | 354 return false; |
356 } | 355 |
357 | 356 push_node(constant.basic_type(), makecon(con_type)); |
358 // success | |
359 return true; | 357 return true; |
360 } | 358 } |
361 | |
362 | 359 |
363 | 360 |
364 //============================================================================= | 361 //============================================================================= |
365 void Parse::do_anewarray() { | 362 void Parse::do_anewarray() { |
366 bool will_link; | 363 bool will_link; |