/*
 * Copyright (C) 2015 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.
 */

#include "intrinsics.h"

#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/utils.h"
#include "class_linker.h"
#include "dex/invoke_type.h"
#include "driver/compiler_options.h"
#include "gc/space/image_space.h"
#include "image-inl.h"
#include "intrinsic_objects.h"
#include "nodes.h"
#include "obj_ptr-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"

namespace art {

std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) {
  switch (intrinsic) {
    case Intrinsics::kNone:
      os << "None";
      break;
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
    case Intrinsics::k ## Name: \
      os << # Name; \
      break;
#include "intrinsics_list.h"
      INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
#undef STATIC_INTRINSICS_LIST
#undef VIRTUAL_INTRINSICS_LIST
#undef OPTIMIZING_INTRINSICS
  }
  return os;
}

static const char kIntegerCacheDescriptor[] = "Ljava/lang/Integer$IntegerCache;";
static const char kIntegerDescriptor[] = "Ljava/lang/Integer;";
static const char kIntegerArrayDescriptor[] = "[Ljava/lang/Integer;";
static const char kLowFieldName[] = "low";
static const char kHighFieldName[] = "high";
static const char kValueFieldName[] = "value";

static ObjPtr<mirror::ObjectArray<mirror::Object>> GetBootImageLiveObjects()
    REQUIRES_SHARED(Locks::mutator_lock_) {
  gc::Heap* heap = Runtime::Current()->GetHeap();
  const std::vector<gc::space::ImageSpace*>& boot_image_spaces = heap->GetBootImageSpaces();
  DCHECK(!boot_image_spaces.empty());
  const ImageHeader& main_header = boot_image_spaces[0]->GetImageHeader();
  ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects =
      ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(
          main_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kBootImageLiveObjects));
  DCHECK(boot_image_live_objects != nullptr);
  DCHECK(heap->ObjectIsInBootImageSpace(boot_image_live_objects));
  return boot_image_live_objects;
}

static ObjPtr<mirror::Class> LookupInitializedClass(Thread* self,
                                                    ClassLinker* class_linker,
                                                    const char* descriptor)
        REQUIRES_SHARED(Locks::mutator_lock_) {
  ObjPtr<mirror::Class> klass =
      class_linker->LookupClass(self, descriptor, /* class_loader */ nullptr);
  DCHECK(klass != nullptr);
  DCHECK(klass->IsInitialized());
  return klass;
}

static ObjPtr<mirror::ObjectArray<mirror::Object>> GetIntegerCacheArray(
    ObjPtr<mirror::Class> cache_class) REQUIRES_SHARED(Locks::mutator_lock_) {
  ArtField* cache_field = cache_class->FindDeclaredStaticField("cache", kIntegerArrayDescriptor);
  DCHECK(cache_field != nullptr);
  return ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(cache_field->GetObject(cache_class));
}

static int32_t GetIntegerCacheField(ObjPtr<mirror::Class> cache_class, const char* field_name)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ArtField* field = cache_class->FindDeclaredStaticField(field_name, "I");
  DCHECK(field != nullptr);
  return field->GetInt(cache_class);
}

static bool CheckIntegerCache(Thread* self,
                              ClassLinker* class_linker,
                              ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects,
                              ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_cache)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  DCHECK(boot_image_cache != nullptr);

  // Since we have a cache in the boot image, both java.lang.Integer and
  // java.lang.Integer$IntegerCache must be initialized in the boot image.
  ObjPtr<mirror::Class> cache_class =
      LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor);
  ObjPtr<mirror::Class> integer_class =
      LookupInitializedClass(self, class_linker, kIntegerDescriptor);

  // Check that the current cache is the same as the `boot_image_cache`.
  ObjPtr<mirror::ObjectArray<mirror::Object>> current_cache = GetIntegerCacheArray(cache_class);
  if (current_cache != boot_image_cache) {
    return false;  // Messed up IntegerCache.cache.
  }

  // Check that the range matches the boot image cache length.
  int32_t low = GetIntegerCacheField(cache_class, kLowFieldName);
  int32_t high = GetIntegerCacheField(cache_class, kHighFieldName);
  if (boot_image_cache->GetLength() != high - low + 1) {
    return false;  // Messed up IntegerCache.low or IntegerCache.high.
  }

  // Check that the elements match the boot image intrinsic objects and check their values as well.
  ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I");
  DCHECK(value_field != nullptr);
  for (int32_t i = 0, len = boot_image_cache->GetLength(); i != len; ++i) {
    ObjPtr<mirror::Object> boot_image_object =
        IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, i);
    DCHECK(Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(boot_image_object));
    // No need for read barrier for comparison with a boot image object.
    ObjPtr<mirror::Object> current_object =
        boot_image_cache->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>(i);
    if (boot_image_object != current_object) {
      return false;  // Messed up IntegerCache.cache[i]
    }
    if (value_field->GetInt(boot_image_object) != low + i) {
      return false;  // Messed up IntegerCache.cache[i].value.
    }
  }

  return true;
}

void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke,
                                                      CodeGenerator* codegen,
                                                      Location return_location,
                                                      Location first_argument_location) {
  // The intrinsic will call if it needs to allocate a j.l.Integer.
  LocationSummary::CallKind call_kind = LocationSummary::kCallOnMainOnly;
  const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
  if (compiler_options.IsBootImage()) {
    // Piggyback on the method load kind to determine whether we can use PC-relative addressing.
    // This should cover both the testing config (non-PIC boot image) and codegens that reject
    // PC-relative load kinds and fall back to the runtime call.
    if (!invoke->AsInvokeStaticOrDirect()->HasPcRelativeMethodLoadKind()) {
      return;
    }
    if (!compiler_options.IsImageClass(kIntegerCacheDescriptor) ||
        !compiler_options.IsImageClass(kIntegerDescriptor)) {
      return;
    }
    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    Thread* self = Thread::Current();
    ScopedObjectAccess soa(self);
    ObjPtr<mirror::Class> cache_class = class_linker->LookupClass(
        self, kIntegerCacheDescriptor, /* class_loader */ nullptr);
    DCHECK(cache_class != nullptr);
    if (UNLIKELY(!cache_class->IsInitialized())) {
      LOG(WARNING) << "Image class " << cache_class->PrettyDescriptor() << " is uninitialized.";
      return;
    }
    ObjPtr<mirror::Class> integer_class =
        class_linker->LookupClass(self, kIntegerDescriptor, /* class_loader */ nullptr);
    DCHECK(integer_class != nullptr);
    if (UNLIKELY(!integer_class->IsInitialized())) {
      LOG(WARNING) << "Image class " << integer_class->PrettyDescriptor() << " is uninitialized.";
      return;
    }
    int32_t low = GetIntegerCacheField(cache_class, kLowFieldName);
    int32_t high = GetIntegerCacheField(cache_class, kHighFieldName);
    if (kIsDebugBuild) {
      ObjPtr<mirror::ObjectArray<mirror::Object>> current_cache = GetIntegerCacheArray(cache_class);
      CHECK(current_cache != nullptr);
      CHECK_EQ(current_cache->GetLength(), high - low + 1);
      ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I");
      CHECK(value_field != nullptr);
      for (int32_t i = 0, len = current_cache->GetLength(); i != len; ++i) {
        ObjPtr<mirror::Object> current_object = current_cache->GetWithoutChecks(i);
        CHECK(current_object != nullptr);
        CHECK_EQ(value_field->GetInt(current_object), low + i);
      }
    }
    if (invoke->InputAt(0)->IsIntConstant()) {
      int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue();
      if (static_cast<uint32_t>(value) - static_cast<uint32_t>(low) <
          static_cast<uint32_t>(high - low + 1)) {
        // No call, we shall use direct pointer to the Integer object.
        call_kind = LocationSummary::kNoCall;
      }
    }
  } else {
    Runtime* runtime = Runtime::Current();
    if (runtime->GetHeap()->GetBootImageSpaces().empty()) {
      return;  // Running without boot image, cannot use required boot image objects.
    }
    Thread* self = Thread::Current();
    ScopedObjectAccess soa(self);
    ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects = GetBootImageLiveObjects();
    ObjPtr<mirror::ObjectArray<mirror::Object>> cache =
        IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects);
    if (cache == nullptr) {
      return;  // No cache in the boot image.
    }
    if (runtime->UseJitCompilation()) {
      if (!CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache)) {
        return;  // The cache was somehow messed up, probably by using reflection.
      }
    } else {
      DCHECK(runtime->IsAotCompiler());
      DCHECK(CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache));
      if (invoke->InputAt(0)->IsIntConstant()) {
        int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue();
        // Retrieve the `value` from the lowest cached Integer.
        ObjPtr<mirror::Object> low_integer =
            IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, 0u);
        ObjPtr<mirror::Class> integer_class =
            low_integer->GetClass<kVerifyNone, kWithoutReadBarrier>();
        ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I");
        DCHECK(value_field != nullptr);
        int32_t low = value_field->GetInt(low_integer);
        if (static_cast<uint32_t>(value) - static_cast<uint32_t>(low) <
            static_cast<uint32_t>(cache->GetLength())) {
          // No call, we shall use direct pointer to the Integer object. Note that we cannot
          // do this for JIT as the "low" can change through reflection before emitting the code.
          call_kind = LocationSummary::kNoCall;
        }
      }
    }
  }

  ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetAllocator();
  LocationSummary* locations = new (allocator) LocationSummary(invoke, call_kind, kIntrinsified);
  if (call_kind == LocationSummary::kCallOnMainOnly) {
    locations->SetInAt(0, Location::RegisterOrConstant(invoke->InputAt(0)));
    locations->AddTemp(first_argument_location);
    locations->SetOut(return_location);
  } else {
    locations->SetInAt(0, Location::ConstantLocation(invoke->InputAt(0)->AsConstant()));
    locations->SetOut(Location::RequiresRegister());
  }
}

static int32_t GetIntegerCacheLowFromIntegerCache(Thread* self, ClassLinker* class_linker)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ObjPtr<mirror::Class> cache_class =
      LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor);
  return GetIntegerCacheField(cache_class, kLowFieldName);
}

static uint32_t CalculateBootImageOffset(ObjPtr<mirror::Object> object)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  gc::Heap* heap = Runtime::Current()->GetHeap();
  DCHECK(heap->ObjectIsInBootImageSpace(object));
  return reinterpret_cast<const uint8_t*>(object.Ptr()) - heap->GetBootImageSpaces()[0]->Begin();
}

inline IntrinsicVisitor::IntegerValueOfInfo::IntegerValueOfInfo()
    : value_offset(0),
      low(0),
      length(0u),
      integer_boot_image_offset(kInvalidReference),
      value_boot_image_reference(kInvalidReference) {}

IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo(
    HInvoke* invoke, const CompilerOptions& compiler_options) {
  // Note that we could cache all of the data looked up here. but there's no good
  // location for it. We don't want to add it to WellKnownClasses, to avoid creating global
  // jni values. Adding it as state to the compiler singleton seems like wrong
  // separation of concerns.
  // The need for this data should be pretty rare though.

  // Note that at this point we can no longer abort the code generation. Therefore,
  // we need to provide data that shall not lead to a crash even if the fields were
  // modified through reflection since ComputeIntegerValueOfLocations() when JITting.

  Runtime* runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  IntegerValueOfInfo info;
  if (compiler_options.IsBootImage()) {
    ObjPtr<mirror::Class> integer_class =
        LookupInitializedClass(self, class_linker, kIntegerDescriptor);
    ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I");
    DCHECK(value_field != nullptr);
    info.value_offset = value_field->GetOffset().Uint32Value();
    ObjPtr<mirror::Class> cache_class =
        LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor);
    info.low = GetIntegerCacheField(cache_class, kLowFieldName);
    int32_t high = GetIntegerCacheField(cache_class, kHighFieldName);
    info.length = dchecked_integral_cast<uint32_t>(high - info.low + 1);

    info.integer_boot_image_offset = IntegerValueOfInfo::kInvalidReference;
    if (invoke->InputAt(0)->IsIntConstant()) {
      int32_t input_value = invoke->InputAt(0)->AsIntConstant()->GetValue();
      uint32_t index = static_cast<uint32_t>(input_value) - static_cast<uint32_t>(info.low);
      if (index < static_cast<uint32_t>(info.length)) {
        info.value_boot_image_reference = IntrinsicObjects::EncodePatch(
            IntrinsicObjects::PatchType::kIntegerValueOfObject, index);
      } else {
        // Not in the cache.
        info.value_boot_image_reference = IntegerValueOfInfo::kInvalidReference;
      }
    } else {
      info.array_data_boot_image_reference =
          IntrinsicObjects::EncodePatch(IntrinsicObjects::PatchType::kIntegerValueOfArray);
    }
  } else {
    ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects = GetBootImageLiveObjects();
    ObjPtr<mirror::Object> low_integer =
        IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, 0u);
    ObjPtr<mirror::Class> integer_class = low_integer->GetClass<kVerifyNone, kWithoutReadBarrier>();
    ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I");
    DCHECK(value_field != nullptr);
    info.value_offset = value_field->GetOffset().Uint32Value();
    if (runtime->UseJitCompilation()) {
      // Use the current `IntegerCache.low` for JIT to avoid truly surprising behavior if the
      // code messes up the `value` field in the lowest cached Integer using reflection.
      info.low = GetIntegerCacheLowFromIntegerCache(self, class_linker);
    } else {
      // For app AOT, the `low_integer->value` should be the same as `IntegerCache.low`.
      info.low = value_field->GetInt(low_integer);
      DCHECK_EQ(info.low, GetIntegerCacheLowFromIntegerCache(self, class_linker));
    }
    // Do not look at `IntegerCache.high`, use the immutable length of the cache array instead.
    info.length = dchecked_integral_cast<uint32_t>(
        IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects)->GetLength());

    info.integer_boot_image_offset = CalculateBootImageOffset(integer_class);
    if (invoke->InputAt(0)->IsIntConstant()) {
      int32_t input_value = invoke->InputAt(0)->AsIntConstant()->GetValue();
      uint32_t index = static_cast<uint32_t>(input_value) - static_cast<uint32_t>(info.low);
      if (index < static_cast<uint32_t>(info.length)) {
        ObjPtr<mirror::Object> integer =
            IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, index);
        info.value_boot_image_reference = CalculateBootImageOffset(integer);
      } else {
        // Not in the cache.
        info.value_boot_image_reference = IntegerValueOfInfo::kInvalidReference;
      }
    } else {
      info.array_data_boot_image_reference =
          CalculateBootImageOffset(boot_image_live_objects) +
          IntrinsicObjects::GetIntegerValueOfArrayDataOffset(boot_image_live_objects).Uint32Value();
    }
  }

  return info;
}

}  // namespace art
