hotspot/src/share/vm/oops/methodOop.cpp
changeset 360 21d113ecbf6a
parent 351 74ef5746f624
child 363 99d43e8a76ad
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
   428 
   428 
   429 
   429 
   430 bool methodOopDesc::is_accessor() const {
   430 bool methodOopDesc::is_accessor() const {
   431   if (code_size() != 5) return false;
   431   if (code_size() != 5) return false;
   432   if (size_of_parameters() != 1) return false;
   432   if (size_of_parameters() != 1) return false;
   433   if (Bytecodes::java_code_at(code_base()+0) != Bytecodes::_aload_0 ) return false;
   433   methodOop m = (methodOop)this;  // pass to code_at() to avoid method_from_bcp
   434   if (Bytecodes::java_code_at(code_base()+1) != Bytecodes::_getfield) return false;
   434   if (Bytecodes::java_code_at(code_base()+0, m) != Bytecodes::_aload_0 ) return false;
   435   Bytecodes::Code ret_bc = Bytecodes::java_code_at(code_base()+4);
   435   if (Bytecodes::java_code_at(code_base()+1, m) != Bytecodes::_getfield) return false;
   436   if (Bytecodes::java_code_at(code_base()+4) != Bytecodes::_areturn &&
   436   if (Bytecodes::java_code_at(code_base()+4, m) != Bytecodes::_areturn &&
   437       Bytecodes::java_code_at(code_base()+4) != Bytecodes::_ireturn ) return false;
   437       Bytecodes::java_code_at(code_base()+4, m) != Bytecodes::_ireturn ) return false;
   438   return true;
   438   return true;
   439 }
   439 }
   440 
   440 
   441 
   441 
   442 bool methodOopDesc::is_initializer() const {
   442 bool methodOopDesc::is_initializer() const {
   953 
   953 
   954 
   954 
   955 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
   955 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
   956 static void reorder_based_on_method_index(objArrayOop methods,
   956 static void reorder_based_on_method_index(objArrayOop methods,
   957                                           objArrayOop annotations,
   957                                           objArrayOop annotations,
   958                                           oop* temp_array) {
   958                                           GrowableArray<oop>* temp_array) {
   959   if (annotations == NULL) {
   959   if (annotations == NULL) {
   960     return;
   960     return;
   961   }
   961   }
   962 
   962 
   963   int length = methods->length();
   963   int length = methods->length();
   964   int i;
   964   int i;
   965   // Copy to temp array
   965   // Copy to temp array
   966   memcpy(temp_array, annotations->obj_at_addr(0), length * sizeof(oop));
   966   temp_array->clear();
       
   967   for (i = 0; i < length; i++) {
       
   968     temp_array->append(annotations->obj_at(i));
       
   969   }
   967 
   970 
   968   // Copy back using old method indices
   971   // Copy back using old method indices
   969   for (i = 0; i < length; i++) {
   972   for (i = 0; i < length; i++) {
   970     methodOop m = (methodOop) methods->obj_at(i);
   973     methodOop m = (methodOop) methods->obj_at(i);
   971     annotations->obj_at_put(i, temp_array[m->method_idnum()]);
   974     annotations->obj_at_put(i, temp_array->at(m->method_idnum()));
   972   }
   975   }
   973 }
   976 }
   974 
   977 
   975 
   978 
   976 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
   979 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
   995       }
   998       }
   996     }
   999     }
   997 
  1000 
   998     // Use a simple bubble sort for small number of methods since
  1001     // Use a simple bubble sort for small number of methods since
   999     // qsort requires a functional pointer call for each comparison.
  1002     // qsort requires a functional pointer call for each comparison.
  1000     if (length < 8) {
  1003     if (UseCompressedOops || length < 8) {
  1001       bool sorted = true;
  1004       bool sorted = true;
  1002       for (int i=length-1; i>0; i--) {
  1005       for (int i=length-1; i>0; i--) {
  1003         for (int j=0; j<i; j++) {
  1006         for (int j=0; j<i; j++) {
  1004           methodOop m1 = (methodOop)methods->obj_at(j);
  1007           methodOop m1 = (methodOop)methods->obj_at(j);
  1005           methodOop m2 = (methodOop)methods->obj_at(j+1);
  1008           methodOop m2 = (methodOop)methods->obj_at(j+1);
  1008             methods->obj_at_put(j+1, m1);
  1011             methods->obj_at_put(j+1, m1);
  1009             sorted = false;
  1012             sorted = false;
  1010           }
  1013           }
  1011         }
  1014         }
  1012         if (sorted) break;
  1015         if (sorted) break;
  1013         sorted = true;
  1016           sorted = true;
  1014       }
  1017       }
  1015     } else {
  1018     } else {
       
  1019       // XXX This doesn't work for UseCompressedOops because the compare fn
       
  1020       // will have to decode the methodOop anyway making it not much faster
       
  1021       // than above.
  1016       compareFn compare = (compareFn) (idempotent ? method_compare_idempotent : method_compare);
  1022       compareFn compare = (compareFn) (idempotent ? method_compare_idempotent : method_compare);
  1017       qsort(methods->obj_at_addr(0), length, oopSize, compare);
  1023       qsort(methods->base(), length, heapOopSize, compare);
  1018     }
  1024     }
  1019 
  1025 
  1020     // Sort annotations if necessary
  1026     // Sort annotations if necessary
  1021     assert(methods_annotations == NULL           || methods_annotations->length() == methods->length(), "");
  1027     assert(methods_annotations == NULL           || methods_annotations->length() == methods->length(), "");
  1022     assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
  1028     assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
  1023     assert(methods_default_annotations == NULL   || methods_default_annotations->length() == methods->length(), "");
  1029     assert(methods_default_annotations == NULL   || methods_default_annotations->length() == methods->length(), "");
  1024     if (do_annotations) {
  1030     if (do_annotations) {
       
  1031       ResourceMark rm;
  1025       // Allocate temporary storage
  1032       // Allocate temporary storage
  1026       oop* temp_array = NEW_RESOURCE_ARRAY(oop, length);
  1033       GrowableArray<oop>* temp_array = new GrowableArray<oop>(length);
  1027       reorder_based_on_method_index(methods, methods_annotations, temp_array);
  1034       reorder_based_on_method_index(methods, methods_annotations, temp_array);
  1028       reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
  1035       reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
  1029       reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
  1036       reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
  1030     }
  1037     }
  1031 
  1038