/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_IMTABLE_INL_H_
#define ART_RUNTIME_IMTABLE_INL_H_

#include "imtable.h"

#include "art_method-inl.h"
#include "dex/dex_file.h"
#include "dex/utf.h"

namespace art {

static constexpr bool kImTableHashUseName = true;
static constexpr bool kImTableHashUseCoefficients = true;

// Magic configuration that minimizes some common runtime calls.
static constexpr uint32_t kImTableHashCoefficientClass = 427;
static constexpr uint32_t kImTableHashCoefficientName = 16;
static constexpr uint32_t kImTableHashCoefficientSignature = 14;

inline void ImTable::GetImtHashComponents(ArtMethod* method,
                                          uint32_t* class_hash,
                                          uint32_t* name_hash,
                                          uint32_t* signature_hash) {
  if (kImTableHashUseName) {
    if (method->IsProxyMethod()) {
      *class_hash = 0;
      *name_hash = 0;
      *signature_hash = 0;
      return;
    }

    const DexFile* dex_file = method->GetDexFile();
    const dex::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());

    // Class descriptor for the class component.
    *class_hash = ComputeModifiedUtf8Hash(dex_file->GetMethodDeclaringClassDescriptor(method_id));

    // Method name for the method component.
    *name_hash = ComputeModifiedUtf8Hash(dex_file->GetMethodName(method_id));

    const dex::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);

    // Read the proto for the signature component.
    uint32_t tmp = ComputeModifiedUtf8Hash(
        dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_)));

    // Mix in the argument types.
    // Note: we could consider just using the shorty. This would be faster, at the price of
    //       potential collisions.
    const dex::TypeList* param_types = dex_file->GetProtoParameters(proto_id);
    if (param_types != nullptr) {
      for (size_t i = 0; i != param_types->Size(); ++i) {
        const dex::TypeItem& type = param_types->GetTypeItem(i);
        tmp = 31 * tmp + ComputeModifiedUtf8Hash(
            dex_file->GetTypeDescriptor(dex_file->GetTypeId(type.type_idx_)));
      }
    }

    *signature_hash = tmp;
    return;
  } else {
    *class_hash = method->GetDexMethodIndex();
    *name_hash = 0;
    *signature_hash = 0;
    return;
  }
}

inline uint32_t ImTable::GetImtIndex(ArtMethod* method) {
  uint32_t class_hash, name_hash, signature_hash;
  GetImtHashComponents(method, &class_hash, &name_hash, &signature_hash);

  uint32_t mixed_hash;
  if (!kImTableHashUseCoefficients) {
    mixed_hash = class_hash + name_hash + signature_hash;
  } else {
    mixed_hash = kImTableHashCoefficientClass * class_hash +
                 kImTableHashCoefficientName * name_hash +
                 kImTableHashCoefficientSignature * signature_hash;
  }

  return mixed_hash % ImTable::kSize;
}

}  // namespace art

#endif  // ART_RUNTIME_IMTABLE_INL_H_

