< prev index next >

src/hotspot/share/interpreter/rewriter.cpp

Print this page

154       case Bytecodes::_istore_0:
155       case Bytecodes::_lstore_0:
156       case Bytecodes::_fstore_0:
157       case Bytecodes::_dstore_0:
158       case Bytecodes::_astore_0:
159         THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
160                   "can't overwrite local 0 in Object.<init>");
161         break;
162 
163       default:
164         break;
165     }
166   }
167 }
168 
169 
170 // Rewrite a classfile-order CP index into a native-order CPC index.
171 void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) {
172   address p = bcp + offset;
173   if (!reverse) {
174     int  cp_index    = Bytes::get_Java_u2(p);
175     int  cache_index = cp_entry_to_cp_cache(cp_index);
176     Bytes::put_native_u2(p, cache_index);
177     if (!_method_handle_invokers.is_empty())
178       maybe_rewrite_invokehandle(p - 1, cp_index, cache_index, reverse);
179   } else {
180     int cache_index = Bytes::get_native_u2(p);
181     int pool_index = cp_cache_entry_pool_index(cache_index);
182     Bytes::put_Java_u2(p, pool_index);
183     if (!_method_handle_invokers.is_empty())
184       maybe_rewrite_invokehandle(p - 1, pool_index, cache_index, reverse);
185   }
186 }
187 
188 // If the constant pool entry for invokespecial is InterfaceMethodref,
189 // we need to add a separate cpCache entry for its resolution, because it is
190 // different than the resolution for invokeinterface with InterfaceMethodref.
191 // These cannot share cpCache entries.
192 void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
193   address p = bcp + offset;
194   if (!reverse) {
195     int cp_index = Bytes::get_Java_u2(p);
196     if (_pool->tag_at(cp_index).is_interface_method()) {
197       int cache_index = add_invokespecial_cp_cache_entry(cp_index);
198       if (cache_index != (int)(jushort) cache_index) {
199         *invokespecial_error = true;
200       }
201       Bytes::put_native_u2(p, cache_index);
202     } else {
203       rewrite_member_reference(bcp, offset, reverse);
204     }
205   } else {
206     rewrite_member_reference(bcp, offset, reverse);
207   }
208 }
209 
210 
211 // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
212 void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {
213   if (!reverse) {
214     if ((*opc) == (u1)Bytecodes::_invokevirtual ||
215         // allow invokespecial as an alias, although it would be very odd:
216         (*opc) == (u1)Bytecodes::_invokespecial) {
217       assert(_pool->tag_at(cp_index).is_method(), "wrong index");
218       // Determine whether this is a signature-polymorphic method.
219       if (cp_index >= _method_handle_invokers.length())  return;
220       int status = _method_handle_invokers.at(cp_index);
221       assert(status >= -1 && status <= 1, "oob tri-state");
222       if (status == 0) {
223         if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
224             MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),
225                                                          _pool->name_ref_at(cp_index))) {
226           // we may need a resolved_refs entry for the appendix
227           add_invokedynamic_resolved_references_entry(cp_index, cache_index);
228           status = +1;
229         } else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&
230                    MethodHandles::is_signature_polymorphic_name(vmClasses::VarHandle_klass(),

435           // Check if any final field of the class given as parameter is modified
436           // outside of initializer methods of the class. Fields that are modified
437           // are marked with a flag. For marked fields, the compilers do not perform
438           // constant folding (as the field can be changed after initialization).
439           //
440           // The check is performed after verification and only if verification has
441           // succeeded. Therefore, the class is guaranteed to be well-formed.
442           InstanceKlass* klass = method->method_holder();
443           u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
444           constantPoolHandle cp(thread, method->constants());
445           Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
446 
447           if (klass->name() == ref_class_name) {
448             Symbol* field_name = cp->name_ref_at(bc_index);
449             Symbol* field_sig = cp->signature_ref_at(bc_index);
450 
451             fieldDescriptor fd;
452             if (klass->find_field(field_name, field_sig, &fd) != NULL) {
453               if (fd.access_flags().is_final()) {
454                 if (fd.access_flags().is_static()) {
455                   if (!method->is_static_initializer()) {
456                     fd.set_has_initialized_final_update(true);
457                   }
458                 } else {
459                   if (!method->is_object_initializer()) {
460                     fd.set_has_initialized_final_update(true);
461                   }
462                 }
463               }
464             }
465           }
466         }
467       }
468       // fall through
469       case Bytecodes::_getstatic      : // fall through
470       case Bytecodes::_getfield       : // fall through

471       case Bytecodes::_invokevirtual  : // fall through
472       case Bytecodes::_invokestatic   :
473       case Bytecodes::_invokeinterface:
474       case Bytecodes::_invokehandle   : // if reverse=true
475         rewrite_member_reference(bcp, prefix_length+1, reverse);
476         break;
477       case Bytecodes::_invokedynamic:
478         rewrite_invokedynamic(bcp, prefix_length+1, reverse);
479         break;
480       case Bytecodes::_ldc:
481       case Bytecodes::_fast_aldc:  // if reverse=true
482         maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
483         break;
484       case Bytecodes::_ldc_w:
485       case Bytecodes::_fast_aldc_w:  // if reverse=true
486         maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
487         break;
488       case Bytecodes::_jsr            : // fall through
489       case Bytecodes::_jsr_w          : nof_jsrs++;                   break;
490       case Bytecodes::_monitorenter   : // fall through

154       case Bytecodes::_istore_0:
155       case Bytecodes::_lstore_0:
156       case Bytecodes::_fstore_0:
157       case Bytecodes::_dstore_0:
158       case Bytecodes::_astore_0:
159         THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
160                   "can't overwrite local 0 in Object.<init>");
161         break;
162 
163       default:
164         break;
165     }
166   }
167 }
168 
169 
170 // Rewrite a classfile-order CP index into a native-order CPC index.
171 void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) {
172   address p = bcp + offset;
173   if (!reverse) {
174     int cp_index    = Bytes::get_Java_u2(p);
175     int  cache_index = cp_entry_to_cp_cache(cp_index);
176     Bytes::put_native_u2(p, cache_index);
177     if (!_method_handle_invokers.is_empty())
178       maybe_rewrite_invokehandle(p - 1, cp_index, cache_index, reverse);
179   } else {
180     int cache_index = Bytes::get_native_u2(p);
181     int pool_index = cp_cache_entry_pool_index(cache_index);
182     Bytes::put_Java_u2(p, pool_index);
183     if (!_method_handle_invokers.is_empty())
184       maybe_rewrite_invokehandle(p - 1, pool_index, cache_index, reverse);
185   }
186 }
187 
188 // If the constant pool entry for invokespecial is InterfaceMethodref,
189 // we need to add a separate cpCache entry for its resolution, because it is
190 // different than the resolution for invokeinterface with InterfaceMethodref.
191 // These cannot share cpCache entries.
192 void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
193   address p = bcp + offset;
194   if (!reverse) {
195     int cp_index = Bytes::get_Java_u2(p);
196     if (_pool->tag_at(cp_index).is_interface_method()) {
197       int cache_index = add_invokespecial_cp_cache_entry(cp_index);
198       if (cache_index != (int)(jushort) cache_index) {
199         *invokespecial_error = true;
200       }
201       Bytes::put_native_u2(p, cache_index);
202     } else {
203       rewrite_member_reference(bcp, offset, reverse);
204     }
205   } else {
206     rewrite_member_reference(bcp, offset, reverse);
207   }
208 }
209 

210 // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
211 void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {
212   if (!reverse) {
213     if ((*opc) == (u1)Bytecodes::_invokevirtual ||
214         // allow invokespecial as an alias, although it would be very odd:
215         (*opc) == (u1)Bytecodes::_invokespecial) {
216       assert(_pool->tag_at(cp_index).is_method(), "wrong index");
217       // Determine whether this is a signature-polymorphic method.
218       if (cp_index >= _method_handle_invokers.length())  return;
219       int status = _method_handle_invokers.at(cp_index);
220       assert(status >= -1 && status <= 1, "oob tri-state");
221       if (status == 0) {
222         if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
223             MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),
224                                                          _pool->name_ref_at(cp_index))) {
225           // we may need a resolved_refs entry for the appendix
226           add_invokedynamic_resolved_references_entry(cp_index, cache_index);
227           status = +1;
228         } else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&
229                    MethodHandles::is_signature_polymorphic_name(vmClasses::VarHandle_klass(),

434           // Check if any final field of the class given as parameter is modified
435           // outside of initializer methods of the class. Fields that are modified
436           // are marked with a flag. For marked fields, the compilers do not perform
437           // constant folding (as the field can be changed after initialization).
438           //
439           // The check is performed after verification and only if verification has
440           // succeeded. Therefore, the class is guaranteed to be well-formed.
441           InstanceKlass* klass = method->method_holder();
442           u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
443           constantPoolHandle cp(thread, method->constants());
444           Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
445 
446           if (klass->name() == ref_class_name) {
447             Symbol* field_name = cp->name_ref_at(bc_index);
448             Symbol* field_sig = cp->signature_ref_at(bc_index);
449 
450             fieldDescriptor fd;
451             if (klass->find_field(field_name, field_sig, &fd) != NULL) {
452               if (fd.access_flags().is_final()) {
453                 if (fd.access_flags().is_static()) {
454                   if (!method->is_class_initializer()) {
455                     fd.set_has_initialized_final_update(true);
456                   }
457                 } else {
458                   if (!method->is_object_constructor()) {
459                     fd.set_has_initialized_final_update(true);
460                   }
461                 }
462               }
463             }
464           }
465         }
466       }
467       // fall through
468       case Bytecodes::_getstatic      : // fall through
469       case Bytecodes::_getfield       : // fall through
470       case Bytecodes::_withfield     : // fall through but may require more checks for correctness
471       case Bytecodes::_invokevirtual  : // fall through
472       case Bytecodes::_invokestatic   :
473       case Bytecodes::_invokeinterface:
474       case Bytecodes::_invokehandle   : // if reverse=true
475         rewrite_member_reference(bcp, prefix_length+1, reverse);
476         break;
477       case Bytecodes::_invokedynamic:
478         rewrite_invokedynamic(bcp, prefix_length+1, reverse);
479         break;
480       case Bytecodes::_ldc:
481       case Bytecodes::_fast_aldc:  // if reverse=true
482         maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
483         break;
484       case Bytecodes::_ldc_w:
485       case Bytecodes::_fast_aldc_w:  // if reverse=true
486         maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
487         break;
488       case Bytecodes::_jsr            : // fall through
489       case Bytecodes::_jsr_w          : nof_jsrs++;                   break;
490       case Bytecodes::_monitorenter   : // fall through
< prev index next >