コード例 #1
0
ファイル: signature.hpp プロジェクト: dain/graal
  uint64_t fingerprint() {
    // See if we fingerprinted this method already
    if (mh->constMethod()->fingerprint() != CONST64(0)) {
      return mh->constMethod()->fingerprint();
    }

    if (mh->size_of_parameters() > max_size_of_parameters ) {
      _fingerprint = UCONST64(-1);
      mh->constMethod()->set_fingerprint(_fingerprint);
      return _fingerprint;
    }

    assert( (int)mh->result_type() <= (int)result_feature_mask, "bad result type");
    _fingerprint = mh->result_type();
    _fingerprint <<= static_feature_size;
    if (mh->is_static())  _fingerprint |= 1;
    _shift_count = result_feature_size + static_feature_size;
    iterate_parameters();
    _fingerprint |= ((uint64_t)done_parm) << _shift_count;// mark end of sig
    mh->constMethod()->set_fingerprint(_fingerprint);
    return _fingerprint;
  }
// Write one method_info structure
// JVMSpec|   method_info {
// JVMSpec|     u2 access_flags;
// JVMSpec|     u2 name_index;
// JVMSpec|     u2 descriptor_index;
// JVMSpec|     u2 attributes_count;
// JVMSpec|     attribute_info attributes[attributes_count];
// JVMSpec|   }
void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
  AccessFlags access_flags = method->access_flags();
  ConstMethod* const_method = method->constMethod();
  u2 generic_signature_index = const_method->generic_signature_index();
  AnnotationArray* anno = method->annotations();
  AnnotationArray* param_anno = method->parameter_annotations();
  AnnotationArray* default_anno = method->annotation_default();
  AnnotationArray* type_anno = method->type_annotations();

  // skip generated default interface methods
  if (method->is_overpass()) {
    return;
  }

  write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
  write_u2(const_method->name_index());
  write_u2(const_method->signature_index());

  // write attributes in the same order javac does, so we can test with byte for
  // byte comparison
  int attr_count = 0;
  if (const_method->code_size() != 0) {
    ++attr_count;     // has Code attribute
  }
  if (const_method->has_checked_exceptions()) {
    ++attr_count;     // has Exceptions attribute
  }
  if (default_anno != NULL) {
    ++attr_count;     // has AnnotationDefault attribute
  }
  // Deprecated attribute would go here
  if (access_flags.is_synthetic()) { // FIXME
    // ++attr_count;
  }
  if (generic_signature_index != 0) {
    ++attr_count;
  }
  if (anno != NULL) {
    ++attr_count;     // has RuntimeVisibleAnnotations attribute
  }
  if (param_anno != NULL) {
    ++attr_count;     // has RuntimeVisibleParameterAnnotations attribute
  }
  if (type_anno != NULL) {
    ++attr_count;     // has RuntimeVisibleTypeAnnotations attribute
  }

  write_u2(attr_count);
  if (const_method->code_size() > 0) {
    write_code_attribute(method);
  }
  if (const_method->has_checked_exceptions()) {
    write_exceptions_attribute(const_method);
  }
  if (default_anno != NULL) {
    write_annotations_attribute("AnnotationDefault", default_anno);
  }
  // Deprecated attribute would go here
  if (access_flags.is_synthetic()) {
    // write_synthetic_attribute();
  }
  if (generic_signature_index != 0) {
    write_signature_attribute(generic_signature_index);
  }
  if (anno != NULL) {
    write_annotations_attribute("RuntimeVisibleAnnotations", anno);
  }
  if (param_anno != NULL) {
    write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
  }
  if (type_anno != NULL) {
    write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
  }
}
// Write Code attribute
// JVMSpec|   Code_attribute {
// JVMSpec|     u2 attribute_name_index;
// JVMSpec|     u4 attribute_length;
// JVMSpec|     u2 max_stack;
// JVMSpec|     u2 max_locals;
// JVMSpec|     u4 code_length;
// JVMSpec|     u1 code[code_length];
// JVMSpec|     u2 exception_table_length;
// JVMSpec|     {       u2 start_pc;
// JVMSpec|             u2 end_pc;
// JVMSpec|             u2  handler_pc;
// JVMSpec|             u2  catch_type;
// JVMSpec|     }       exception_table[exception_table_length];
// JVMSpec|     u2 attributes_count;
// JVMSpec|     attribute_info attributes[attributes_count];
// JVMSpec|   }
void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
  ConstMethod* const_method = method->constMethod();
  u2 line_num_cnt = 0;
  int stackmap_len = 0;
  int local_variable_table_length = 0;
  int local_variable_type_table_length = 0;

  // compute number and length of attributes
  int attr_count = 0;
  int attr_size = 0;
  if (const_method->has_linenumber_table()) {
    line_num_cnt = line_number_table_entries(method);
    if (line_num_cnt != 0) {
      ++attr_count;
      // Compute the complete size of the line number table attribute:
      //      LineNumberTable_attribute {
      //        u2 attribute_name_index;
      //        u4 attribute_length;
      //        u2 line_number_table_length;
      //        {  u2 start_pc;
      //           u2 line_number;
      //        } line_number_table[line_number_table_length];
      //      }
      attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
    }
  }
  if (method->has_stackmap_table()) {
    stackmap_len = method->stackmap_data()->length();
    if (stackmap_len != 0) {
      ++attr_count;
      // Compute the  size of the stack map table attribute (VM stores raw):
      //      StackMapTable_attribute {
      //        u2 attribute_name_index;
      //        u4 attribute_length;
      //        u2 number_of_entries;
      //        stack_map_frame_entries[number_of_entries];
      //      }
      attr_size += 2 + 4 + stackmap_len;
    }
  }
  if (method->has_localvariable_table()) {
    local_variable_table_length = method->localvariable_table_length();
    if (local_variable_table_length != 0) {
      ++attr_count;
      // Compute the size of the local variable table attribute (VM stores raw):
      // LocalVariableTable_attribute {
      //   u2 attribute_name_index;
      //   u4 attribute_length;
      //   u2 local_variable_table_length;
      //   {
      //     u2 start_pc;
      //     u2 length;
      //     u2 name_index;
      //     u2 descriptor_index;
      //     u2 index;
      //   }
      attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);

      // Local variables with generic signatures must have LVTT entries
      LocalVariableTableElement *elem = method->localvariable_table_start();
      for (int idx = 0; idx < local_variable_table_length; idx++) {
        if (elem[idx].signature_cp_index != 0) {
          local_variable_type_table_length++;
        }
      }

      if (local_variable_type_table_length != 0) {
        ++attr_count;
        // Compute the size of the local variable type table attribute (VM stores raw):
        // LocalVariableTypeTable_attribute {
        //   u2 attribute_name_index;
        //   u4 attribute_length;
        //   u2 local_variable_type_table_length;
        //   {
        //     u2 start_pc;
        //     u2 length;
        //     u2 name_index;
        //     u2 signature_index;
        //     u2 index;
        //   }
        attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);
      }
    }
  }

  ExceptionTable exception_table(method());
  int exception_table_length = exception_table.length();
  int code_size = const_method->code_size();
  int size =
    2+2+4 +                                // max_stack, max_locals, code_length
    code_size +                            // code
    2 +                                    // exception_table_length
    (2+2+2+2) * exception_table_length +   // exception_table
    2 +                                    // attributes_count
    attr_size;                             // attributes

  write_attribute_name_index("Code");
  write_u4(size);
  write_u2(method->verifier_max_stack());
  write_u2(method->max_locals());
  write_u4(code_size);
  copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
  write_u2(exception_table_length);
  for (int index = 0; index < exception_table_length; index++) {
    write_u2(exception_table.start_pc(index));
    write_u2(exception_table.end_pc(index));
    write_u2(exception_table.handler_pc(index));
    write_u2(exception_table.catch_type_index(index));
  }
  write_u2(attr_count);
  if (line_num_cnt != 0) {
    write_line_number_table_attribute(method, line_num_cnt);
  }
  if (stackmap_len != 0) {
    write_stackmap_table_attribute(method, stackmap_len);
  }
  if (local_variable_table_length != 0) {
    write_local_variable_table_attribute(method, local_variable_table_length);
  }
  if (local_variable_type_table_length != 0) {
    write_local_variable_type_table_attribute(method, local_variable_type_table_length);
  }
}
// Write Code attribute
// JVMSpec|   Code_attribute {
// JVMSpec|   	u2 attribute_name_index;
// JVMSpec|   	u4 attribute_length;
// JVMSpec|   	u2 max_stack;
// JVMSpec|   	u2 max_locals;
// JVMSpec|   	u4 code_length;
// JVMSpec|   	u1 code[code_length];
// JVMSpec|   	u2 exception_table_length;
// JVMSpec|   	{    	u2 start_pc;
// JVMSpec|   	      	u2 end_pc;
// JVMSpec|   	      	u2  handler_pc;
// JVMSpec|   	      	u2  catch_type;
// JVMSpec|   	}	exception_table[exception_table_length];
// JVMSpec|   	u2 attributes_count;
// JVMSpec|   	attribute_info attributes[attributes_count];
// JVMSpec|   }
void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
  constMethodHandle const_method(thread(), method->constMethod());
  u2 line_num_cnt = 0;
  int stackmap_len = 0;

  // compute number and length of attributes -- FIXME: for now no LVT
  int attr_count = 0;
  int attr_size = 0;
  if (const_method->has_linenumber_table()) {
    line_num_cnt = line_number_table_entries(method);  
    if (line_num_cnt != 0) {
      ++attr_count;
      // Compute the complete size of the line number table attribute:
      //      LineNumberTable_attribute {
      //      	u2 attribute_name_index;
      //      	u4 attribute_length;
      //      	u2 line_number_table_length;
      //      	{  u2 start_pc;	     
      //      	   u2 line_number;	     
      //      	} line_number_table[line_number_table_length];
      //      }
      attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
    }
  }
  if (method->has_stackmap_table()) {
    stackmap_len = method->stackmap_data()->length();
    if (stackmap_len != 0) {
      ++attr_count;
      // Compute the  size of the stack map table attribute (VM stores raw):
      //      StackMapTable_attribute {
      //      	u2 attribute_name_index;
      //      	u4 attribute_length;
      //      	u2 number_of_entries;
      //      	stack_map_frame_entries[number_of_entries];
      //      }
      attr_size += 2 + 4 + stackmap_len;
    }
  }

  typeArrayHandle exception_table(thread(), const_method->exception_table());
  int exception_table_length = exception_table->length();
  int exception_table_entries = exception_table_length / 4;
  int code_size = const_method->code_size();
  int size = 
    2+2+4 +                                // max_stack, max_locals, code_length
    code_size +                            // code
    2 +                                    // exception_table_length
    (2+2+2+2) * exception_table_entries +  // exception_table
    2 +                                    // attributes_count
    attr_size;                             // attributes

  write_attribute_name_index("Code");
  write_u4(size);
  write_u2(method->max_stack());
  write_u2(method->max_locals());
  write_u4(code_size);
  copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
  write_u2(exception_table_entries);
  for (int index = 0; index < exception_table_length; ) {
    write_u2(exception_table->int_at(index++));
    write_u2(exception_table->int_at(index++));
    write_u2(exception_table->int_at(index++));
    write_u2(exception_table->int_at(index++));
  }
  write_u2(attr_count);
  if (line_num_cnt != 0) {
    write_line_number_table_attribute(method, line_num_cnt);
  }
  if (stackmap_len != 0) {
    write_stackmap_table_attribute(method, stackmap_len);
  }

  // FIXME: write LVT attribute
}