// Copyright 2011 Google Inc. All Rights Reserved.

#include "runtime.h"

#include <cstdio>
#include <cstdlib>
#include <limits>
#include <vector>

#include "UniquePtr.h"
#include "class_linker.h"
#include "heap.h"
#include "image.h"
#include "intern_table.h"
#include "jni_internal.h"
#include "oat_file.h"
#include "signal_catcher.h"
#include "space.h"
#include "thread.h"
#include "thread_list.h"

// TODO: this drags in cutil/log.h, which conflicts with our logging.h.
#include "JniConstants.h"

namespace art {

Runtime* Runtime::instance_ = NULL;

Runtime::Runtime()
    : verbose_startup_(false),
      default_stack_size_(Thread::kDefaultStackSize),
      thread_list_(NULL),
      intern_table_(NULL),
      class_linker_(NULL),
      signal_catcher_(NULL),
      java_vm_(NULL),
      jni_stub_array_(NULL),
      abstract_method_error_stub_array_(NULL),
      started_(false),
      vfprintf_(NULL),
      exit_(NULL),
      abort_(NULL),
      stats_enabled_(false) {
  for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
    resolution_stub_array_[i] = NULL;
  }
  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
    callee_save_method_[i] = NULL;
  }
}

Runtime::~Runtime() {
  // Make sure our internal threads are dead before we start tearing down things they're using.
  delete signal_catcher_;
  // TODO: GC thread.

  // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended.
  delete thread_list_;

  delete class_linker_;
  Heap::Destroy();
  delete intern_table_;
  delete java_vm_;
  Thread::Shutdown();
  // TODO: acquire a static mutex on Runtime to avoid racing.
  CHECK(instance_ == NULL || instance_ == this);
  instance_ = NULL;
}

void Runtime::Abort(const char* file, int line) {
  // Get any pending output out of the way.
  fflush(NULL);

  // Many people have difficulty distinguish aborts from crashes,
  // so be explicit.
  LogMessage(file, line, ERROR, -1).stream() << "Runtime aborting...";

  // Perform any platform-specific pre-abort actions.
  PlatformAbort(file, line);

  // use abort hook if we have one
  if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) {
    Runtime::Current()->abort_();
    // notreached
  }

  // If we call abort(3) on a device, all threads in the process
  // receive SIGABRT.  debuggerd dumps the stack trace of the main
  // thread, whether or not that was the thread that failed.  By
  // stuffing a value into a bogus address, we cause a segmentation
  // fault in the current thread, and get a useful log from debuggerd.
  // We can also trivially tell the difference between a VM crash and
  // a deliberate abort by looking at the fault address.
  *reinterpret_cast<char*>(0xdeadd00d) = 38;
  abort();
  // notreached
}

void Runtime::CallExitHook(jint status) {
  if (exit_ != NULL) {
    ScopedThreadStateChange tsc(Thread::Current(), Thread::kNative);
    exit_(status);
    LOG(WARNING) << "Exit hook returned instead of exiting!";
  }
}

// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify
// memory sizes.  [kK] indicates kilobytes, [mM] megabytes, and
// [gG] gigabytes.
//
// "s" should point just past the "-Xm?" part of the string.
// "div" specifies a divisor, e.g. 1024 if the value must be a multiple
// of 1024.
//
// The spec says the -Xmx and -Xms options must be multiples of 1024.  It
// doesn't say anything about -Xss.
//
// Returns 0 (a useless size) if "s" is malformed or specifies a low or
// non-evenly-divisible value.
//
size_t ParseMemoryOption(const char *s, size_t div) {
  // strtoul accepts a leading [+-], which we don't want,
  // so make sure our string starts with a decimal digit.
  if (isdigit(*s)) {
    const char *s2;
    size_t val = strtoul(s, (char **)&s2, 10);
    if (s2 != s) {
      // s2 should be pointing just after the number.
      // If this is the end of the string, the user
      // has specified a number of bytes.  Otherwise,
      // there should be exactly one more character
      // that specifies a multiplier.
      if (*s2 != '\0') {
        // The remainder of the string is either a single multiplier
        // character, or nothing to indicate that the value is in
        // bytes.
        char c = *s2++;
        if (*s2 == '\0') {
          size_t mul;
          if (c == '\0') {
            mul = 1;
          } else if (c == 'k' || c == 'K') {
            mul = KB;
          } else if (c == 'm' || c == 'M') {
            mul = MB;
          } else if (c == 'g' || c == 'G') {
            mul = GB;
          } else {
            // Unknown multiplier character.
            return 0;
          }

          if (val <= std::numeric_limits<size_t>::max() / mul) {
            val *= mul;
          } else {
            // Clamp to a multiple of 1024.
            val = std::numeric_limits<size_t>::max() & ~(1024-1);
          }
        } else {
          // There's more than one character after the numeric part.
          return 0;
        }
      }
      // The man page says that a -Xm value must be a multiple of 1024.
      if (val % div == 0) {
        return val;
      }
    }
  }
  return 0;
}

void LoadJniLibrary(JavaVMExt* vm, const char* name) {
  // TODO: OS_SHARED_LIB_FORMAT_STR
  std::string mapped_name(StringPrintf("lib%s.so", name));
  std::string reason;
  if (!vm->LoadNativeLibrary(mapped_name, NULL, reason)) {
    LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": "
               << reason;
  }
}

Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) {
  UniquePtr<ParsedOptions> parsed(new ParsedOptions());
  const char* boot_class_path = getenv("BOOTCLASSPATH");
  if (boot_class_path != NULL) {
    parsed->boot_class_path_ = getenv("BOOTCLASSPATH");
  }
  const char* class_path = getenv("CLASSPATH");
  if (class_path != NULL) {
    parsed->class_path_ = getenv("CLASSPATH");
  }
#ifdef NDEBUG
  // -Xcheck:jni is off by default for regular builds...
  parsed->check_jni_ = false;
#else
  // ...but on by default in debug builds.
  parsed->check_jni_ = true;
#endif

  parsed->heap_initial_size_ = Heap::kInitialSize;
  parsed->heap_maximum_size_ = Heap::kMaximumSize;
  parsed->stack_size_ = Thread::kDefaultStackSize;

  parsed->hook_vfprintf_ = vfprintf;
  parsed->hook_exit_ = exit;
  parsed->hook_abort_ = abort;

  for (size_t i = 0; i < options.size(); ++i) {
    const StringPiece& option = options[i].first;
    if (false) {
      LOG(INFO) << "option[" << i << "]=" << option;
    }
    if (option.starts_with("-Xbootclasspath:")) {
      parsed->boot_class_path_ = option.substr(strlen("-Xbootclasspath:")).data();
    } else if (option == "-classpath" || option == "-cp") {
      // TODO: support -Djava.class.path
      i++;
      if (i == options.size()) {
        // TODO: usage
        LOG(FATAL) << "Missing required class path value for " << option;
        return NULL;
      }
      const StringPiece& value = options[i].first;
      parsed->class_path_ = value.data();
    } else if (option.starts_with("-Ximage:")) {
      parsed->images_.push_back(option.substr(strlen("-Ximage:")).data());
    } else if (option.starts_with("-Xcheck:jni")) {
      parsed->check_jni_ = true;
    } else if (option.starts_with("-Xms")) {
      size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).data(), 1024);
      if (size == 0) {
        if (ignore_unrecognized) {
          continue;
        }
        // TODO: usage
        LOG(FATAL) << "Failed to parse " << option;
        return NULL;
      }
      parsed->heap_initial_size_ = size;
    } else if (option.starts_with("-Xmx")) {
      size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).data(), 1024);
      if (size == 0) {
        if (ignore_unrecognized) {
          continue;
        }
        // TODO: usage
        LOG(FATAL) << "Failed to parse " << option;
        return NULL;
      }
      parsed->heap_maximum_size_ = size;
    } else if (option.starts_with("-Xss")) {
      size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).data(), 1);
      if (size == 0) {
        if (ignore_unrecognized) {
          continue;
        }
        // TODO: usage
        LOG(FATAL) << "Failed to parse " << option;
        return NULL;
      }
      parsed->stack_size_ = size;
    } else if (option.starts_with("-D")) {
      parsed->properties_.push_back(option.substr(strlen("-D")).data());
    } else if (option.starts_with("-Xjnitrace:")) {
      parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:")).data();
    } else if (option.starts_with("-verbose:")) {
      std::vector<std::string> verbose_options;
      Split(option.substr(strlen("-verbose:")).data(), ',', verbose_options);
      for (size_t i = 0; i < verbose_options.size(); ++i) {
        parsed->verbose_.insert(verbose_options[i]);
      }
    } else if (option == "vfprintf") {
      parsed->hook_vfprintf_ = reinterpret_cast<int (*)(FILE *, const char*, va_list)>(options[i].second);
    } else if (option == "exit") {
      parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second);
    } else if (option == "abort") {
      parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second);
    } else if (option == "host-prefix") {
      parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second);
    } else {
      if (!ignore_unrecognized) {
        // TODO: print usage via vfprintf
        LOG(ERROR) << "Unrecognized option " << option;
        // TODO: this should exit, but for now tolerate unknown options
        //return NULL;
      }
    }
  }

  LOG(INFO) << "CheckJNI is " << (parsed->check_jni_ ? "on" : "off");

  return parsed.release();
}

Runtime* Runtime::Create(const Options& options, bool ignore_unrecognized) {
  // TODO: acquire a static mutex on Runtime to avoid racing.
  if (Runtime::instance_ != NULL) {
    return NULL;
  }
  instance_ = new Runtime;
  if (!instance_->Init(options, ignore_unrecognized)) {
    delete instance_;
    instance_ = NULL;
  }
  return instance_;
}

void Runtime::Start() {
  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::Start entering";
  }

  CHECK(host_prefix_.empty()) << host_prefix_;

  InitNativeMethods();

  Thread::FinishStartup();

  class_linker_->RunRootClinits();

  // Class::AllocObject asserts that all objects allocated better be
  // initialized after Runtime::IsStarted is true, so this needs to
  // come after ClassLinker::RunRootClinits.
  started_ = true;

  StartDaemonThreads();

  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::Start exiting";
  }
}

void Runtime::StartDaemonThreads() {
  signal_catcher_ = new SignalCatcher;

  Thread* self = Thread::Current();
  JNIEnv* env = self->GetJniEnv();
  jclass c = env->FindClass("java/lang/Daemons");
  CHECK(c != NULL);
  jmethodID mid = env->GetStaticMethodID(c, "start", "()V");
  CHECK(mid != NULL);
  env->CallStaticVoidMethod(c, mid);
}

bool Runtime::IsStarted() const {
  return started_;
}

bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
  CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);

  UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized));
  if (options.get() == NULL) {
    LOG(ERROR) << "Failed to parse options";
    return false;
  }
  verbose_startup_ = options->IsVerbose("startup");
  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::Init -verbose:startup enabled";
  }

  host_prefix_ = options->host_prefix_;
  boot_class_path_ = options->boot_class_path_;
  class_path_ = options->class_path_;
  properties_ = options->properties_;

  vfprintf_ = options->hook_vfprintf_;
  exit_ = options->hook_exit_;
  abort_ = options->hook_abort_;

  default_stack_size_ = options->stack_size_;

  thread_list_ = new ThreadList(options->IsVerbose("thread"));
  intern_table_ = new InternTable;

  Heap::Init(options->heap_initial_size_, options->heap_maximum_size_, options->images_);

  BlockSignals();

  java_vm_ = new JavaVMExt(this, options.get());

  Thread::Startup();

  // ClassLinker needs an attached thread, but we can't fully attach a thread
  // without creating objects.
  Thread::Attach(this, "main", false);

  CHECK_GE(Heap::GetSpaces().size(), 1U);
  class_linker_ = ((Heap::GetSpaces()[0]->IsImageSpace())
                   ? ClassLinker::Create(intern_table_)
                   : ClassLinker::Create(options->boot_class_path_, intern_table_));

  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::Init exiting";
  }
  return true;
}

void Runtime::InitNativeMethods() {
  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::InitNativeMethods entering";
  }
  Thread* self = Thread::Current();
  JNIEnv* env = self->GetJniEnv();

  // Must be in the kNative state for calling native methods (JNI_OnLoad code).
  ScopedThreadStateChange tsc(self, Thread::kNative);

  // First set up JniConstants, which is used by both the runtime's built-in native
  // methods and libcore.
  JniConstants::init(env);

  // Then set up the native methods provided by the runtime itself.
  RegisterRuntimeNativeMethods(env);

  // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad.
  // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's
  // the library that implements System.loadLibrary!
  LoadJniLibrary(instance_->GetJavaVM(), "javacore");
  if (IsVerboseStartup()) {
    LOG(INFO) << "Runtime::InitNativeMethods exiting";
  }
}

void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) {
#define REGISTER(FN) extern void FN(JNIEnv*); FN(env)
  REGISTER(register_dalvik_system_DexFile);
  REGISTER(register_dalvik_system_VMDebug);
  REGISTER(register_dalvik_system_VMRuntime);
  REGISTER(register_dalvik_system_VMStack);
  REGISTER(register_dalvik_system_Zygote);
  REGISTER(register_java_lang_Class);
  REGISTER(register_java_lang_Object);
  REGISTER(register_java_lang_Runtime);
  REGISTER(register_java_lang_String);
  REGISTER(register_java_lang_System);
  REGISTER(register_java_lang_Thread);
  REGISTER(register_java_lang_Throwable);
  REGISTER(register_java_lang_VMClassLoader);
  REGISTER(register_java_lang_reflect_Array);
  REGISTER(register_java_lang_reflect_Constructor);
  REGISTER(register_java_lang_reflect_Field);
  REGISTER(register_java_lang_reflect_Method);
  //REGISTER(register_java_lang_reflect_Proxy);
  REGISTER(register_java_util_concurrent_atomic_AtomicLong);
  REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
  //REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal);
  REGISTER(register_sun_misc_Unsafe);
#undef REGISTER
}

void Runtime::Dump(std::ostream& os) {
  // TODO: dump other runtime statistics?
  os << "Loaded classes: " << class_linker_->NumLoadedClasses() << "\n";
  os << "Intern table size: " << GetInternTable()->Size() << "\n";
  // LOGV("VM stats: meth=%d ifld=%d sfld=%d linear=%d",
  //    gDvm.numDeclaredMethods,
  //    gDvm.numDeclaredInstFields,
  //    gDvm.numDeclaredStaticFields,
  //    gDvm.pBootLoaderAlloc->curOffset);
  // LOGI("GC precise methods: %d", dvmPointerSetGetCount(gDvm.preciseMethods));
  os << "\n";

  thread_list_->Dump(os);
}

void Runtime::SetStatsEnabled(bool new_state) {
  if (new_state == true) {
    GetStats()->Clear(~0);
    // TODO: wouldn't it make more sense to clear _all_ threads' stats?
    Thread::Current()->GetStats()->Clear(~0);
  }
  stats_enabled_ = new_state;
}

void Runtime::ResetStats(int kinds) {
  GetStats()->Clear(kinds & 0xffff);
  // TODO: wouldn't it make more sense to clear _all_ threads' stats?
  Thread::Current()->GetStats()->Clear(kinds >> 16);
}

RuntimeStats* Runtime::GetStats() {
  return &stats_;
}

int32_t Runtime::GetStat(int kind) {
  RuntimeStats* stats;
  if (kind < (1<<16)) {
    stats = GetStats();
  } else {
    stats = Thread::Current()->GetStats();
    kind >>= 16;
  }
  switch (kind) {
  case KIND_ALLOCATED_OBJECTS:
    return stats->allocated_objects;
  case KIND_ALLOCATED_BYTES:
    return stats->allocated_bytes;
  case KIND_FREED_OBJECTS:
    return stats->freed_objects;
  case KIND_FREED_BYTES:
    return stats->freed_bytes;
  case KIND_GC_INVOCATIONS:
    return stats->gc_for_alloc_count;
  case KIND_CLASS_INIT_COUNT:
    return stats->class_init_count;
  case KIND_CLASS_INIT_TIME:
    // Convert ns to us, reduce to 32 bits.
    return (int) (stats->class_init_time_ns / 1000);
  case KIND_EXT_ALLOCATED_OBJECTS:
  case KIND_EXT_ALLOCATED_BYTES:
  case KIND_EXT_FREED_OBJECTS:
  case KIND_EXT_FREED_BYTES:
    return 0;  // backward compatibility
  default:
    CHECK(false);
    return -1; // unreachable
  }
}

void Runtime::BlockSignals() {
  sigset_t sigset;
  if (sigemptyset(&sigset) == -1) {
    PLOG(FATAL) << "sigemptyset failed";
  }
  if (sigaddset(&sigset, SIGPIPE) == -1) {
    PLOG(ERROR) << "sigaddset SIGPIPE failed";
  }
  // SIGQUIT is used to dump the runtime's state (including stack traces).
  if (sigaddset(&sigset, SIGQUIT) == -1) {
    PLOG(ERROR) << "sigaddset SIGQUIT failed";
  }
  // SIGUSR1 is used to initiate a heap dump.
  if (sigaddset(&sigset, SIGUSR1) == -1) {
    PLOG(ERROR) << "sigaddset SIGUSR1 failed";
  }
  CHECK_EQ(sigprocmask(SIG_BLOCK, &sigset, NULL), 0);
}

void Runtime::AttachCurrentThread(const char* name, bool as_daemon) {
  Thread::Attach(instance_, name, as_daemon);
}

void Runtime::DetachCurrentThread() {
  // TODO: check we're not calling DetachCurrentThread from a call stack that
  // includes managed frames. (It's only valid if the stack is all-native.)
  thread_list_->Unregister();
}

void Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
  class_linker_->VisitRoots(visitor, arg);
  intern_table_->VisitRoots(visitor, arg);
  java_vm_->VisitRoots(visitor, arg);
  thread_list_->VisitRoots(visitor, arg);
  visitor(jni_stub_array_, arg);
  visitor(abstract_method_error_stub_array_, arg);
  for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
    visitor(resolution_stub_array_[i], arg);
  }
  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
    visitor(callee_save_method_[i], arg);
  }

  //(*visitor)(&gDvm.outOfMemoryObj, 0, ROOT_VM_INTERNAL, arg);
  //(*visitor)(&gDvm.internalErrorObj, 0, ROOT_VM_INTERNAL, arg);
  //(*visitor)(&gDvm.noClassDefFoundErrorObj, 0, ROOT_VM_INTERNAL, arg);
  UNIMPLEMENTED(WARNING) << "some roots not marked";
}

bool Runtime::HasJniStubArray() const {
  return jni_stub_array_ != NULL;
}

ByteArray* Runtime::GetJniStubArray() const {
  CHECK(jni_stub_array_ != NULL);
  return jni_stub_array_;
}

void Runtime::SetJniStubArray(ByteArray* jni_stub_array) {
  CHECK(jni_stub_array != NULL);
  CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array);
  jni_stub_array_ = jni_stub_array;
}

bool Runtime::HasAbstractMethodErrorStubArray() const {
  return abstract_method_error_stub_array_ != NULL;
}

ByteArray* Runtime::GetAbstractMethodErrorStubArray() const {
  CHECK(abstract_method_error_stub_array_ != NULL);
  return abstract_method_error_stub_array_;
}

void Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) {
  CHECK(abstract_method_error_stub_array != NULL);
  CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array);
  abstract_method_error_stub_array_ = abstract_method_error_stub_array;
}


Runtime::TrampolineType Runtime::GetTrampolineType(Method* method) {
  if (method == NULL) {
    return Runtime::kUnknownMethod;
  } else if (method->IsStatic()) {
    return Runtime::kStaticMethod;
  } else {
    return Runtime::kInstanceMethod;
  }
}

bool Runtime::HasResolutionStubArray(TrampolineType type) const {
  return resolution_stub_array_[type] != NULL;
}

ByteArray* Runtime::GetResolutionStubArray(TrampolineType type) const {
  CHECK(HasResolutionStubArray(type));
  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType));
  return resolution_stub_array_[type];
}

void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) {
  CHECK(resolution_stub_array != NULL);
  CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array);
  resolution_stub_array_[type] = resolution_stub_array;
}

Method* Runtime::CreateCalleeSaveMethod(InstructionSet insns, CalleeSaveType type) {
  Class* method_class = Method::GetMethodClass();
  Method* method = down_cast<Method*>(method_class->AllocObject());
  method->SetDeclaringClass(method_class);
  const char* name;
  if (type == kSaveAll) {
    name = "$$$callee_save_method$$$";
  } else if (type == kRefsOnly) {
    name = "$$$refs_only_callee_save_method$$$";
  } else {
    DCHECK(type == kRefsAndArgs);
    name = "$$$refs_and_args_callee_save_method$$$";
  }
  method->SetName(intern_table_->InternStrong(name));
  method->SetSignature(intern_table_->InternStrong("()V"));
  method->SetCodeArray(NULL, insns);
  if ((insns == kThumb2) || (insns == kArm)) {
    uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6)  | (1 << art::arm::R7) |
                          (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11);
    uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3);
    uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9);
    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills :0) |
                           (type == kSaveAll ? all_spills :0) | (1 << art::arm::LR);
    uint32_t fp_all_spills = (1 << art::arm::S0)  | (1 << art::arm::S1)  | (1 << art::arm::S2) |
                             (1 << art::arm::S3)  | (1 << art::arm::S4)  | (1 << art::arm::S5) |
                             (1 << art::arm::S6)  | (1 << art::arm::S7)  | (1 << art::arm::S8) |
                             (1 << art::arm::S9)  | (1 << art::arm::S10) | (1 << art::arm::S11) |
                             (1 << art::arm::S12) | (1 << art::arm::S13) | (1 << art::arm::S14) |
                             (1 << art::arm::S15) | (1 << art::arm::S16) | (1 << art::arm::S17) |
                             (1 << art::arm::S18) | (1 << art::arm::S19) | (1 << art::arm::S20) |
                             (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) |
                             (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) |
                             (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) |
                             (1 << art::arm::S30) | (1 << art::arm::S31);
    uint32_t fp_spills = type == kSaveAll ? fp_all_spills : 0;
    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
                                 __builtin_popcount(fp_spills) /* fprs */ +
                                 1 /* Method* */) * kPointerSize, kStackAlignment);
    method->SetFrameSizeInBytes(frame_size);
    method->SetReturnPcOffsetInBytes(frame_size - kPointerSize);
    method->SetCoreSpillMask(core_spills);
    method->SetFpSpillMask(fp_spills);
  } else if (insns == kX86) {
    method->SetFrameSizeInBytes(32);
    method->SetReturnPcOffsetInBytes(28);
    method->SetCoreSpillMask((1 << art::x86::EBX) | (1 << art::x86::EBP) | (1 << art::x86::ESI) |
                             (1 << art::x86::EDI));
    method->SetFpSpillMask(0);
  } else {
    UNIMPLEMENTED(FATAL);
  }
  return method;
}

bool Runtime::HasCalleeSaveMethod(CalleeSaveType type) const {
  return callee_save_method_[type] != NULL;
}

// Returns a special method that describes all callee saves being spilled to the stack.
Method* Runtime::GetCalleeSaveMethod(CalleeSaveType type) const {
  CHECK(HasCalleeSaveMethod(type));
  return callee_save_method_[type];
}

void Runtime::SetCalleeSaveMethod(Method* method, CalleeSaveType type) {
  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
  callee_save_method_[type] = method;
}

}  // namespace art
