114 |
114 |
115 // Generate code for the object pointer. |
115 // Generate code for the object pointer. |
116 Node* obj; |
116 Node* obj; |
117 if (is_field) { |
117 if (is_field) { |
118 int obj_depth = is_get ? 0 : field->type()->size(); |
118 int obj_depth = is_get ? 0 : field->type()->size(); |
119 obj = do_null_check(peek(obj_depth), T_OBJECT); |
119 obj = null_check(peek(obj_depth)); |
120 // Compile-time detect of null-exception? |
120 // Compile-time detect of null-exception? |
121 if (stopped()) return; |
121 if (stopped()) return; |
122 |
122 |
123 #ifdef ASSERT |
123 #ifdef ASSERT |
124 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder()); |
124 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder()); |
125 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed"); |
125 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed"); |
126 #endif |
126 #endif |
127 |
127 |
128 if (is_get) { |
128 if (is_get) { |
129 --_sp; // pop receiver before getting |
129 (void) pop(); // pop receiver before getting |
130 do_get_xxx(obj, field, is_field); |
130 do_get_xxx(obj, field, is_field); |
131 } else { |
131 } else { |
132 do_put_xxx(obj, field, is_field); |
132 do_put_xxx(obj, field, is_field); |
133 --_sp; // pop receiver after putting |
133 (void) pop(); // pop receiver after putting |
134 } |
134 } |
135 } else { |
135 } else { |
136 const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror()); |
136 const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror()); |
137 obj = _gvn.makecon(tip); |
137 obj = _gvn.makecon(tip); |
138 if (is_get) { |
138 if (is_get) { |
228 C->log()->elem("assert_null reason='field' klass='%d'", |
228 C->log()->elem("assert_null reason='field' klass='%d'", |
229 C->log()->identify(field->type())); |
229 C->log()->identify(field->type())); |
230 } |
230 } |
231 // If there is going to be a trap, put it at the next bytecode: |
231 // If there is going to be a trap, put it at the next bytecode: |
232 set_bci(iter().next_bci()); |
232 set_bci(iter().next_bci()); |
233 do_null_assert(peek(), T_OBJECT); |
233 null_assert(peek()); |
234 set_bci(iter().cur_bci()); // put it back |
234 set_bci(iter().cur_bci()); // put it back |
235 } |
235 } |
236 |
236 |
237 // If reference is volatile, prevent following memory ops from |
237 // If reference is volatile, prevent following memory ops from |
238 // floating up past the volatile read. Also prevents commoning |
238 // floating up past the volatile read. Also prevents commoning |
461 // to reexecute the multianewarray bytecode if deoptimization happens. |
461 // to reexecute the multianewarray bytecode if deoptimization happens. |
462 // Do it unconditionally even for one dimension multianewarray. |
462 // Do it unconditionally even for one dimension multianewarray. |
463 // Note: the reexecute bit will be set in GraphKit::add_safepoint_edges() |
463 // Note: the reexecute bit will be set in GraphKit::add_safepoint_edges() |
464 // when AllocateArray node for newarray is created. |
464 // when AllocateArray node for newarray is created. |
465 { PreserveReexecuteState preexecs(this); |
465 { PreserveReexecuteState preexecs(this); |
466 _sp += ndimensions; |
466 inc_sp(ndimensions); |
467 // Pass 0 as nargs since uncommon trap code does not need to restore stack. |
467 // Pass 0 as nargs since uncommon trap code does not need to restore stack. |
468 obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0); |
468 obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0); |
469 } //original reexecute and sp are set back here |
469 } //original reexecute and sp are set back here |
470 push(obj); |
470 push(obj); |
471 return; |
471 return; |
490 length[3], length[4]); |
490 length[3], length[4]); |
491 } else { |
491 } else { |
492 // Create a java array for dimension sizes |
492 // Create a java array for dimension sizes |
493 Node* dims = NULL; |
493 Node* dims = NULL; |
494 { PreserveReexecuteState preexecs(this); |
494 { PreserveReexecuteState preexecs(this); |
495 _sp += ndimensions; |
495 inc_sp(ndimensions); |
496 Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT)))); |
496 Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT)))); |
497 dims = new_array(dims_array_klass, intcon(ndimensions), 0); |
497 dims = new_array(dims_array_klass, intcon(ndimensions), 0); |
498 |
498 |
499 // Fill-in it with values |
499 // Fill-in it with values |
500 for (j = 0; j < ndimensions; j++) { |
500 for (j = 0; j < ndimensions; j++) { |