runtime.cc revision 6c1c69eea21cce39dd043d89368a684d250c9abe
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "runtime.h"
18
19#include <signal.h>
20
21#include <cstdio>
22#include <cstdlib>
23#include <limits>
24#include <vector>
25#include <fstream>
26
27#include "class_linker.h"
28#include "class_loader.h"
29#include "constants_arm.h"
30#include "constants_x86.h"
31#include "debugger.h"
32#include "heap.h"
33#include "image.h"
34#include "intern_table.h"
35#include "jni_internal.h"
36#include "monitor.h"
37#include "oat_file.h"
38#include "ScopedLocalRef.h"
39#include "signal_catcher.h"
40#include "signal_set.h"
41#include "space.h"
42#include "thread.h"
43#include "thread_list.h"
44#include "trace.h"
45#include "UniquePtr.h"
46#include "verifier/method_verifier.h"
47
48// TODO: this drags in cutil/log.h, which conflicts with our logging.h.
49#include "JniConstants.h"
50
51namespace art {
52
53Runtime* Runtime::instance_ = NULL;
54
55Runtime::Runtime()
56    : is_compiler_(false),
57      is_zygote_(false),
58      default_stack_size_(Thread::kDefaultStackSize),
59      heap_(NULL),
60      monitor_list_(NULL),
61      thread_list_(NULL),
62      intern_table_(NULL),
63      class_linker_(NULL),
64      signal_catcher_(NULL),
65      java_vm_(NULL),
66      jni_stub_array_(NULL),
67      abstract_method_error_stub_array_(NULL),
68      resolution_method_(NULL),
69      system_class_loader_(NULL),
70      shutting_down_(false),
71      started_(false),
72      vfprintf_(NULL),
73      exit_(NULL),
74      abort_(NULL),
75      stats_enabled_(false),
76      method_trace_(0),
77      method_trace_file_size_(0),
78      tracer_(NULL),
79      use_compile_time_class_path_(false) {
80  for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
81    resolution_stub_array_[i] = NULL;
82  }
83  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
84    callee_save_method_[i] = NULL;
85  }
86}
87
88Runtime::~Runtime() {
89  shutting_down_ = true;
90
91  if (IsMethodTracingActive()) {
92    Trace::Shutdown();
93  }
94
95  // Make sure our internal threads are dead before we start tearing down things they're using.
96  Dbg::StopJdwp();
97  delete signal_catcher_;
98
99  // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended.
100  delete thread_list_;
101  delete monitor_list_;
102
103  delete class_linker_;
104  delete heap_;
105#if defined(ART_USE_LLVM_COMPILER)
106  verifier::MethodVerifier::DeleteInferredRegCategoryMaps();
107#endif
108  verifier::MethodVerifier::DeleteGcMaps();
109  delete intern_table_;
110  delete java_vm_;
111  Thread::Shutdown();
112  // TODO: acquire a static mutex on Runtime to avoid racing.
113  CHECK(instance_ == NULL || instance_ == this);
114  instance_ = NULL;
115}
116
117static bool gAborting = false;
118
119struct AbortState {
120  void Dump(std::ostream& os) {
121    if (gAborting) {
122      os << "Runtime aborting --- recursively, so no thread-specific detail!\n";
123      return;
124    }
125    gAborting = true;
126    os << "Runtime aborting...\n";
127    if (Runtime::Current() == NULL) {
128      os << "(Runtime does not yet exist!)\n";
129      return;
130    }
131    Thread* self = Thread::Current();
132    if (self == NULL) {
133      os << "(Aborting thread was not attached to runtime!)\n";
134    } else {
135      self->Dump(os);
136      if (self->IsExceptionPending()) {
137        os << "Pending " << PrettyTypeOf(self->GetException()) << " on thread:\n"
138           << self->GetException()->Dump();
139      }
140    }
141  }
142};
143
144static Mutex& GetAbortLock() {
145  static Mutex abort_lock("abort lock");
146  return abort_lock;
147}
148
149void Runtime::Abort() {
150  // Ensure that we don't have multiple threads trying to abort at once,
151  // which would result in significantly worse diagnostics.
152  MutexLock mu(GetAbortLock());
153
154  // Get any pending output out of the way.
155  fflush(NULL);
156
157  // Many people have difficulty distinguish aborts from crashes,
158  // so be explicit.
159  AbortState state;
160  LOG(INTERNAL_FATAL) << Dumpable<AbortState>(state);
161
162  // Call the abort hook if we have one.
163  if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) {
164    LOG(INTERNAL_FATAL) << "Calling abort hook...";
165    Runtime::Current()->abort_();
166    // notreached
167    LOG(INTERNAL_FATAL) << "Unexpectedly returned from abort hook!";
168  }
169
170  // TODO: finish merging patches to fix abort(3) in bionic, then lose this!
171  // Bionic doesn't implement POSIX semantics for abort(3) in a multi-threaded
172  // process, so if we call abort(3) on a device, all threads in the process
173  // receive SIGABRT.  debuggerd dumps the stack trace of the main
174  // thread, whether or not that was the thread that failed.  By
175  // stuffing a value into a bogus address, we cause a segmentation
176  // fault in the current thread, and get a useful log from debuggerd.
177  // We can also trivially tell the difference between a crash and
178  // a deliberate abort by looking at the fault address.
179  *reinterpret_cast<char*>(0xdeadd00d) = 38;
180  abort();
181  // notreached
182}
183
184void Runtime::CallExitHook(jint status) {
185  if (exit_ != NULL) {
186    ScopedThreadStateChange tsc(Thread::Current(), kNative);
187    exit_(status);
188    LOG(WARNING) << "Exit hook returned instead of exiting!";
189  }
190}
191
192// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify
193// memory sizes.  [kK] indicates kilobytes, [mM] megabytes, and
194// [gG] gigabytes.
195//
196// "s" should point just past the "-Xm?" part of the string.
197// "div" specifies a divisor, e.g. 1024 if the value must be a multiple
198// of 1024.
199//
200// The spec says the -Xmx and -Xms options must be multiples of 1024.  It
201// doesn't say anything about -Xss.
202//
203// Returns 0 (a useless size) if "s" is malformed or specifies a low or
204// non-evenly-divisible value.
205//
206size_t ParseMemoryOption(const char* s, size_t div) {
207  // strtoul accepts a leading [+-], which we don't want,
208  // so make sure our string starts with a decimal digit.
209  if (isdigit(*s)) {
210    char* s2;
211    size_t val = strtoul(s, &s2, 10);
212    if (s2 != s) {
213      // s2 should be pointing just after the number.
214      // If this is the end of the string, the user
215      // has specified a number of bytes.  Otherwise,
216      // there should be exactly one more character
217      // that specifies a multiplier.
218      if (*s2 != '\0') {
219        // The remainder of the string is either a single multiplier
220        // character, or nothing to indicate that the value is in
221        // bytes.
222        char c = *s2++;
223        if (*s2 == '\0') {
224          size_t mul;
225          if (c == '\0') {
226            mul = 1;
227          } else if (c == 'k' || c == 'K') {
228            mul = KB;
229          } else if (c == 'm' || c == 'M') {
230            mul = MB;
231          } else if (c == 'g' || c == 'G') {
232            mul = GB;
233          } else {
234            // Unknown multiplier character.
235            return 0;
236          }
237
238          if (val <= std::numeric_limits<size_t>::max() / mul) {
239            val *= mul;
240          } else {
241            // Clamp to a multiple of 1024.
242            val = std::numeric_limits<size_t>::max() & ~(1024-1);
243          }
244        } else {
245          // There's more than one character after the numeric part.
246          return 0;
247        }
248      }
249      // The man page says that a -Xm value must be a multiple of 1024.
250      if (val % div == 0) {
251        return val;
252      }
253    }
254  }
255  return 0;
256}
257
258size_t ParseIntegerOrDie(const std::string& s) {
259  std::string::size_type colon = s.find(':');
260  if (colon == std::string::npos) {
261    LOG(FATAL) << "Missing integer: " << s;
262  }
263  const char* begin = &s[colon + 1];
264  char* end;
265  size_t result = strtoul(begin, &end, 10);
266  if (begin == end || *end != '\0') {
267    LOG(FATAL) << "Failed to parse integer in: " << s;
268  }
269  return result;
270}
271
272void LoadJniLibrary(JavaVMExt* vm, const char* name) {
273  std::string mapped_name(StringPrintf(OS_SHARED_LIB_FORMAT_STR, name));
274  std::string reason;
275  if (!vm->LoadNativeLibrary(mapped_name, NULL, reason)) {
276    LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": "
277               << reason;
278  }
279}
280
281Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) {
282  UniquePtr<ParsedOptions> parsed(new ParsedOptions());
283  const char* boot_class_path_string = getenv("BOOTCLASSPATH");
284  if (boot_class_path_string != NULL) {
285    parsed->boot_class_path_string_ = boot_class_path_string;
286  }
287  const char* class_path_string = getenv("CLASSPATH");
288  if (class_path_string != NULL) {
289    parsed->class_path_string_ = class_path_string;
290  }
291  // -Xcheck:jni is off by default for regular builds but on by default in debug builds.
292  parsed->check_jni_ = kIsDebugBuild;
293
294  parsed->heap_initial_size_ = Heap::kInitialSize;
295  parsed->heap_maximum_size_ = Heap::kMaximumSize;
296  parsed->heap_growth_limit_ = 0;  // 0 means no growth limit
297  parsed->stack_size_ = Thread::kDefaultStackSize;
298
299  parsed->is_compiler_ = false;
300  parsed->is_zygote_ = false;
301
302  parsed->jni_globals_max_ = 0;
303  parsed->lock_profiling_threshold_ = 0;
304  parsed->hook_is_sensitive_thread_ = NULL;
305
306  parsed->hook_vfprintf_ = vfprintf;
307  parsed->hook_exit_ = exit;
308  parsed->hook_abort_ = NULL; // We don't call abort(3) by default; see Runtime::Abort.
309#if defined(__APPLE__)
310  parsed->hook_abort_ = abort; // On the Mac, abort(3) gives better results; see Runtime::InitPlatformSignalHandlers.
311#endif
312
313//  gLogVerbosity.class_linker = true; // TODO: don't check this in!
314//  gLogVerbosity.compiler = true; // TODO: don't check this in!
315//  gLogVerbosity.heap = true; // TODO: don't check this in!
316//  gLogVerbosity.gc = true; // TODO: don't check this in!
317//  gLogVerbosity.jdwp = true; // TODO: don't check this in!
318//  gLogVerbosity.jni = true; // TODO: don't check this in!
319//  gLogVerbosity.monitor = true; // TODO: don't check this in!
320//  gLogVerbosity.startup = true; // TODO: don't check this in!
321//  gLogVerbosity.third_party_jni = true; // TODO: don't check this in!
322//  gLogVerbosity.threads = true; // TODO: don't check this in!
323
324  parsed->method_trace_ = false;
325  parsed->method_trace_file_ = "/data/method-trace-file.bin";
326  parsed->method_trace_file_size_ = 10 * MB;
327
328  for (size_t i = 0; i < options.size(); ++i) {
329    const std::string option(options[i].first);
330    if (true && options[0].first == "-Xzygote") {
331      LOG(INFO) << "option[" << i << "]=" << option;
332    }
333    if (StartsWith(option, "-Xbootclasspath:")) {
334      parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data();
335    } else if (option == "-classpath" || option == "-cp") {
336      // TODO: support -Djava.class.path
337      i++;
338      if (i == options.size()) {
339        // TODO: usage
340        LOG(FATAL) << "Missing required class path value for " << option;
341        return NULL;
342      }
343      const StringPiece& value = options[i].first;
344      parsed->class_path_string_ = value.data();
345    } else if (option == "bootclasspath") {
346      parsed->boot_class_path_
347          = reinterpret_cast<const std::vector<const DexFile*>*>(options[i].second);
348    } else if (StartsWith(option, "-Ximage:")) {
349      parsed->image_ = option.substr(strlen("-Ximage:")).data();
350    } else if (StartsWith(option, "-Xcheck:jni")) {
351      parsed->check_jni_ = true;
352    } else if (StartsWith(option, "-Xrunjdwp:") || StartsWith(option, "-agentlib:jdwp=")) {
353      std::string tail(option.substr(option[1] == 'X' ? 10 : 15));
354      if (tail == "help" || !Dbg::ParseJdwpOptions(tail)) {
355        LOG(FATAL) << "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n"
356                   << "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n";
357        return NULL;
358      }
359    } else if (StartsWith(option, "-Xms")) {
360      size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).c_str(), 1024);
361      if (size == 0) {
362        if (ignore_unrecognized) {
363          continue;
364        }
365        // TODO: usage
366        LOG(FATAL) << "Failed to parse " << option;
367        return NULL;
368      }
369      parsed->heap_initial_size_ = size;
370    } else if (StartsWith(option, "-Xmx")) {
371      size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).c_str(), 1024);
372      if (size == 0) {
373        if (ignore_unrecognized) {
374          continue;
375        }
376        // TODO: usage
377        LOG(FATAL) << "Failed to parse " << option;
378        return NULL;
379      }
380      parsed->heap_maximum_size_ = size;
381    } else if (StartsWith(option, "-XX:HeapGrowthLimit=")) {
382      size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapGrowthLimit=")).c_str(), 1024);
383      if (size == 0) {
384        if (ignore_unrecognized) {
385          continue;
386        }
387        // TODO: usage
388        LOG(FATAL) << "Failed to parse " << option;
389        return NULL;
390      }
391      parsed->heap_growth_limit_ = size;
392    } else if (StartsWith(option, "-Xss")) {
393      size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).c_str(), 1);
394      if (size == 0) {
395        if (ignore_unrecognized) {
396          continue;
397        }
398        // TODO: usage
399        LOG(FATAL) << "Failed to parse " << option;
400        return NULL;
401      }
402      parsed->stack_size_ = size;
403    } else if (StartsWith(option, "-D")) {
404      parsed->properties_.push_back(option.substr(strlen("-D")));
405    } else if (StartsWith(option, "-Xjnitrace:")) {
406      parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:"));
407    } else if (option == "compiler") {
408      parsed->is_compiler_ = true;
409    } else if (option == "-Xzygote") {
410      parsed->is_zygote_ = true;
411    } else if (StartsWith(option, "-verbose:")) {
412      std::vector<std::string> verbose_options;
413      Split(option.substr(strlen("-verbose:")), ',', verbose_options);
414      for (size_t i = 0; i < verbose_options.size(); ++i) {
415        if (verbose_options[i] == "class") {
416          gLogVerbosity.class_linker = true;
417        } else if (verbose_options[i] == "compiler") {
418          gLogVerbosity.compiler = true;
419        } else if (verbose_options[i] == "heap") {
420          gLogVerbosity.heap = true;
421        } else if (verbose_options[i] == "gc") {
422          gLogVerbosity.gc = true;
423        } else if (verbose_options[i] == "jdwp") {
424          gLogVerbosity.jdwp = true;
425        } else if (verbose_options[i] == "jni") {
426          gLogVerbosity.jni = true;
427        } else if (verbose_options[i] == "monitor") {
428          gLogVerbosity.monitor = true;
429        } else if (verbose_options[i] == "startup") {
430          gLogVerbosity.startup = true;
431        } else if (verbose_options[i] == "third-party-jni") {
432          gLogVerbosity.third_party_jni = true;
433        } else if (verbose_options[i] == "threads") {
434          gLogVerbosity.threads = true;
435        } else if (StartsWith(verbose_options[i], "log-to=")) {
436          std::string log_file_name(verbose_options[i].substr(strlen("log-to=")));
437          std::ofstream* log_file = new std::ofstream(log_file_name.c_str());
438          if (log_file->is_open() && log_file->good()) {
439            gLogVerbosity.SetLoggingStream(log_file);
440          } else {
441            LOG(ERROR) << "Fail to open log file: \"" << log_file_name << "\","
442                       << " use default logging stream.";
443          }
444        } else {
445          LOG(WARNING) << "Ignoring unknown -verbose option: " << verbose_options[i];
446        }
447      }
448    } else if (StartsWith(option, "-Xjnigreflimit:")) {
449      parsed->jni_globals_max_ = ParseIntegerOrDie(option);
450    } else if (StartsWith(option, "-Xlockprofthreshold:")) {
451      parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option);
452    } else if (StartsWith(option, "-Xstacktracefile:")) {
453      if (kIsDebugBuild) {
454        // Ignore the zygote and always show stack traces in debug builds.
455      } else {
456        parsed->stack_trace_file_ = option.substr(strlen("-Xstacktracefile:"));
457      }
458    } else if (option == "sensitiveThread") {
459      parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(options[i].second);
460    } else if (option == "vfprintf") {
461      parsed->hook_vfprintf_ = reinterpret_cast<int (*)(FILE *, const char*, va_list)>(options[i].second);
462    } else if (option == "exit") {
463      parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second);
464    } else if (option == "abort") {
465      parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second);
466    } else if (option == "host-prefix") {
467      parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second);
468    } else if (option == "-Xgenregmap" || option == "-Xgc:precise") {
469      // We silently ignore these for backwards compatibility.
470    } else if (option == "-Xmethod-trace") {
471      parsed->method_trace_ = true;
472    } else if (StartsWith(option, "-Xmethod-trace-file:")) {
473      parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:"));
474    } else if (StartsWith(option, "-Xmethod-trace-file-size:")) {
475      parsed->method_trace_file_size_ = ParseIntegerOrDie(option);
476    } else {
477      if (!ignore_unrecognized) {
478        // TODO: print usage via vfprintf
479        LOG(ERROR) << "Unrecognized option " << option;
480        // TODO: this should exit, but for now tolerate unknown options
481        //return NULL;
482      }
483    }
484  }
485
486  if (!parsed->is_compiler_ && parsed->image_.empty()) {
487    parsed->image_ += GetAndroidRoot();
488    parsed->image_ += "/framework/boot.art";
489  }
490  if (parsed->heap_growth_limit_ == 0) {
491    parsed->heap_growth_limit_ = parsed->heap_maximum_size_;
492  }
493
494  LOG(INFO) << "Build type: "
495            << (kIsDebugBuild ? "debug" : "optimized")
496            << "; CheckJNI: " << (parsed->check_jni_ ? "on" : "off");
497
498  return parsed.release();
499}
500
501Runtime* Runtime::Create(const Options& options, bool ignore_unrecognized) {
502  // TODO: acquire a static mutex on Runtime to avoid racing.
503  if (Runtime::instance_ != NULL) {
504    return NULL;
505  }
506  instance_ = new Runtime;
507  if (!instance_->Init(options, ignore_unrecognized)) {
508    delete instance_;
509    instance_ = NULL;
510  }
511  return instance_;
512}
513
514void CreateSystemClassLoader() {
515  if (Runtime::Current()->UseCompileTimeClassPath()) {
516    return;
517  }
518
519  Thread* self = Thread::Current();
520
521  // Must be in the kNative state for calling native methods.
522  CHECK_EQ(self->GetState(), kNative);
523
524  JNIEnv* env = self->GetJniEnv();
525  ScopedLocalRef<jclass> ClassLoader_class(env, env->FindClass("java/lang/ClassLoader"));
526  CHECK(ClassLoader_class.get() != NULL);
527  jmethodID getSystemClassLoader = env->GetStaticMethodID(ClassLoader_class.get(),
528                                                          "getSystemClassLoader",
529                                                          "()Ljava/lang/ClassLoader;");
530  CHECK(getSystemClassLoader != NULL);
531  ScopedLocalRef<jobject> class_loader(env, env->CallStaticObjectMethod(ClassLoader_class.get(),
532                                                                        getSystemClassLoader));
533  CHECK(class_loader.get() != NULL);
534
535  Thread::Current()->SetClassLoaderOverride(Decode<ClassLoader*>(env, class_loader.get()));
536
537  ScopedLocalRef<jclass> Thread_class(env, env->FindClass("java/lang/Thread"));
538  CHECK(Thread_class.get() != NULL);
539  jfieldID contextClassLoader = env->GetFieldID(Thread_class.get(),
540                                                "contextClassLoader",
541                                                "Ljava/lang/ClassLoader;");
542  CHECK(contextClassLoader != NULL);
543  ScopedLocalRef<jobject> self_jobject(env, AddLocalReference<jobject>(env, self->GetPeer()));
544  env->SetObjectField(self_jobject.get(), contextClassLoader, class_loader.get());
545}
546
547void Runtime::Start() {
548  VLOG(startup) << "Runtime::Start entering";
549
550  CHECK(host_prefix_.empty()) << host_prefix_;
551
552  // Relocate the OatFiles (ELF images)
553  class_linker_->RelocateExecutable();
554
555  // Restore main thread state to kNative as expected by native code
556  Thread::Current()->SetState(kNative);
557
558  started_ = true;
559
560  // InitNativeMethods needs to be after started_ so that the classes
561  // it touches will have methods linked to the oat file if necessary.
562  InitNativeMethods();
563
564  Thread::FinishStartup();
565
566  if (!is_zygote_) {
567    DidForkFromZygote();
568  }
569
570  StartDaemonThreads();
571
572  CreateSystemClassLoader();
573
574  Thread::Current()->GetJniEnv()->locals.AssertEmpty();
575
576  VLOG(startup) << "Runtime::Start exiting";
577}
578
579void Runtime::DidForkFromZygote() {
580  is_zygote_ = false;
581
582  StartSignalCatcher();
583
584  // Start the JDWP thread. If the command-line debugger flags specified "suspend=y",
585  // this will pause the runtime, so we probably want this to come last.
586  Dbg::StartJdwp();
587}
588
589void Runtime::StartSignalCatcher() {
590  if (!is_zygote_) {
591    signal_catcher_ = new SignalCatcher(stack_trace_file_);
592  }
593}
594
595void Runtime::StartDaemonThreads() {
596  VLOG(startup) << "Runtime::StartDaemonThreads entering";
597
598  Thread* self = Thread::Current();
599
600  // Must be in the kNative state for calling native methods.
601  CHECK_EQ(self->GetState(), kNative);
602
603  JNIEnv* env = self->GetJniEnv();
604  ScopedLocalRef<jclass> c(env, env->FindClass("java/lang/Daemons"));
605  CHECK(c.get() != NULL);
606  jmethodID mid = env->GetStaticMethodID(c.get(), "start", "()V");
607  CHECK(mid != NULL);
608  env->CallStaticVoidMethod(c.get(), mid);
609  CHECK(!env->ExceptionCheck());
610
611  VLOG(startup) << "Runtime::StartDaemonThreads exiting";
612}
613
614bool Runtime::IsShuttingDown() const {
615  return shutting_down_;
616}
617
618bool Runtime::IsStarted() const {
619  return started_;
620}
621
622bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
623  CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
624
625  UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized));
626  if (options.get() == NULL) {
627    LOG(ERROR) << "Failed to parse options";
628    return false;
629  }
630  VLOG(startup) << "Runtime::Init -verbose:startup enabled";
631
632  SetJniGlobalsMax(options->jni_globals_max_);
633  Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);
634
635  host_prefix_ = options->host_prefix_;
636  boot_class_path_string_ = options->boot_class_path_string_;
637  class_path_string_ = options->class_path_string_;
638  properties_ = options->properties_;
639
640  is_compiler_ = options->is_compiler_;
641  is_zygote_ = options->is_zygote_;
642
643  vfprintf_ = options->hook_vfprintf_;
644  exit_ = options->hook_exit_;
645  abort_ = options->hook_abort_;
646
647  default_stack_size_ = options->stack_size_;
648  stack_trace_file_ = options->stack_trace_file_;
649
650  monitor_list_ = new MonitorList;
651  thread_list_ = new ThreadList;
652  intern_table_ = new InternTable;
653
654  verifier::MethodVerifier::InitGcMaps();
655
656#if defined(ART_USE_LLVM_COMPILER)
657  verifier::MethodVerifier::InitInferredRegCategoryMaps();
658#endif
659
660  heap_ = new Heap(options->heap_initial_size_,
661                   options->heap_growth_limit_,
662                   options->heap_maximum_size_,
663                   options->image_);
664
665  BlockSignals();
666  InitPlatformSignalHandlers();
667
668  java_vm_ = new JavaVMExt(this, options.get());
669
670  Thread::Startup();
671
672  // ClassLinker needs an attached thread, but we can't fully attach a thread
673  // without creating objects. We can't supply a thread group yet; it will be fixed later.
674  Thread::Attach("main", false, NULL);
675
676  // Set us to runnable so tools using a runtime can allocate and GC by default
677  Thread::Current()->SetState(kRunnable);
678
679  // Now we're attached, we can take the heap lock and validate the heap.
680  GetHeap()->EnableObjectValidation();
681
682  CHECK_GE(GetHeap()->GetSpaces().size(), 1U);
683  if (GetHeap()->GetSpaces()[0]->IsImageSpace()) {
684    class_linker_ = ClassLinker::CreateFromImage(intern_table_);
685  } else {
686    CHECK(options->boot_class_path_ != NULL);
687    CHECK_NE(options->boot_class_path_->size(), 0U);
688    class_linker_ = ClassLinker::CreateFromCompiler(*options->boot_class_path_, intern_table_);
689  }
690  CHECK(class_linker_ != NULL);
691
692  method_trace_ = options->method_trace_;
693  method_trace_file_ = options->method_trace_file_;
694  method_trace_file_size_ = options->method_trace_file_size_;
695
696  if (options->method_trace_) {
697    Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, false);
698  }
699
700  VLOG(startup) << "Runtime::Init exiting";
701  return true;
702}
703
704void Runtime::InitNativeMethods() {
705  VLOG(startup) << "Runtime::InitNativeMethods entering";
706  Thread* self = Thread::Current();
707  JNIEnv* env = self->GetJniEnv();
708
709  // Must be in the kNative state for calling native methods (JNI_OnLoad code).
710  CHECK_EQ(self->GetState(), kNative);
711
712  // First set up JniConstants, which is used by both the runtime's built-in native
713  // methods and libcore.
714  JniConstants::init(env);
715
716  // Then set up the native methods provided by the runtime itself.
717  RegisterRuntimeNativeMethods(env);
718
719  // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad.
720  // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's
721  // the library that implements System.loadLibrary!
722  LoadJniLibrary(instance_->GetJavaVM(), "javacore");
723  VLOG(startup) << "Runtime::InitNativeMethods exiting";
724}
725
726void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) {
727#define REGISTER(FN) extern void FN(JNIEnv*); FN(env)
728  // Register Throwable first so that registration of other native methods can throw exceptions
729  REGISTER(register_java_lang_Throwable);
730  REGISTER(register_dalvik_system_DexFile);
731  REGISTER(register_dalvik_system_VMDebug);
732  REGISTER(register_dalvik_system_VMRuntime);
733  REGISTER(register_dalvik_system_VMStack);
734  REGISTER(register_dalvik_system_Zygote);
735  REGISTER(register_java_lang_Class);
736  REGISTER(register_java_lang_Object);
737  REGISTER(register_java_lang_Runtime);
738  REGISTER(register_java_lang_String);
739  REGISTER(register_java_lang_System);
740  REGISTER(register_java_lang_Thread);
741  REGISTER(register_java_lang_VMClassLoader);
742  REGISTER(register_java_lang_reflect_Array);
743  REGISTER(register_java_lang_reflect_Constructor);
744  REGISTER(register_java_lang_reflect_Field);
745  REGISTER(register_java_lang_reflect_Method);
746  REGISTER(register_java_lang_reflect_Proxy);
747  REGISTER(register_java_util_concurrent_atomic_AtomicLong);
748  REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
749  REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal);
750  REGISTER(register_sun_misc_Unsafe);
751#undef REGISTER
752}
753
754void Runtime::DumpForSigQuit(std::ostream& os) {
755  GetClassLinker()->DumpForSigQuit(os);
756  GetInternTable()->DumpForSigQuit(os);
757  GetHeap()->DumpForSigQuit(os);
758  os << "\n";
759
760  thread_list_->DumpForSigQuit(os);
761}
762
763void Runtime::DumpLockHolders(std::ostream& os) {
764  pid_t heap_lock_owner = GetHeap()->GetLockOwner();
765  pid_t thread_list_lock_owner = GetThreadList()->GetLockOwner();
766  pid_t classes_lock_owner = GetClassLinker()->GetClassesLockOwner();
767  pid_t dex_lock_owner = GetClassLinker()->GetDexLockOwner();
768  if ((heap_lock_owner | thread_list_lock_owner | classes_lock_owner | dex_lock_owner) != 0) {
769    os << "Heap lock owner tid: " << heap_lock_owner << "\n"
770       << "ThreadList lock owner tid: " << thread_list_lock_owner << "\n"
771       << "ClassLinker classes lock owner tid: " << classes_lock_owner << "\n"
772       << "ClassLinker dex lock owner tid: " << dex_lock_owner << "\n";
773  }
774}
775
776void Runtime::SetStatsEnabled(bool new_state) {
777  if (new_state == true) {
778    GetStats()->Clear(~0);
779    // TODO: wouldn't it make more sense to clear _all_ threads' stats?
780    Thread::Current()->GetStats()->Clear(~0);
781  }
782  stats_enabled_ = new_state;
783}
784
785void Runtime::ResetStats(int kinds) {
786  GetStats()->Clear(kinds & 0xffff);
787  // TODO: wouldn't it make more sense to clear _all_ threads' stats?
788  Thread::Current()->GetStats()->Clear(kinds >> 16);
789}
790
791RuntimeStats* Runtime::GetStats() {
792  return &stats_;
793}
794
795int32_t Runtime::GetStat(int kind) {
796  RuntimeStats* stats;
797  if (kind < (1<<16)) {
798    stats = GetStats();
799  } else {
800    stats = Thread::Current()->GetStats();
801    kind >>= 16;
802  }
803  switch (kind) {
804  case KIND_ALLOCATED_OBJECTS:
805    return stats->allocated_objects;
806  case KIND_ALLOCATED_BYTES:
807    return stats->allocated_bytes;
808  case KIND_FREED_OBJECTS:
809    return stats->freed_objects;
810  case KIND_FREED_BYTES:
811    return stats->freed_bytes;
812  case KIND_GC_INVOCATIONS:
813    return stats->gc_for_alloc_count;
814  case KIND_CLASS_INIT_COUNT:
815    return stats->class_init_count;
816  case KIND_CLASS_INIT_TIME:
817    // Convert ns to us, reduce to 32 bits.
818    return static_cast<int>(stats->class_init_time_ns / 1000);
819  case KIND_EXT_ALLOCATED_OBJECTS:
820  case KIND_EXT_ALLOCATED_BYTES:
821  case KIND_EXT_FREED_OBJECTS:
822  case KIND_EXT_FREED_BYTES:
823    return 0;  // backward compatibility
824  default:
825    LOG(FATAL) << "Unknown statistic " << kind;
826    return -1; // unreachable
827  }
828}
829
830void Runtime::BlockSignals() {
831  SignalSet signals;
832  signals.Add(SIGPIPE);
833  // SIGQUIT is used to dump the runtime's state (including stack traces).
834  signals.Add(SIGQUIT);
835  // SIGUSR1 is used to initiate a GC.
836  signals.Add(SIGUSR1);
837  signals.Block();
838}
839
840void Runtime::AttachCurrentThread(const char* thread_name, bool as_daemon, Object* thread_group) {
841  Thread::Attach(thread_name, as_daemon, thread_group);
842  if (thread_name == NULL) {
843    LOG(WARNING) << *Thread::Current() << " attached without supplying a name";
844  }
845}
846
847void Runtime::DetachCurrentThread() {
848  if (Thread::Current()->GetTopOfStack().GetSP() != NULL) {
849    LOG(FATAL) << *Thread::Current() << " attempting to detach while still running code";
850  }
851  thread_list_->Unregister();
852}
853
854void Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
855  Dbg::VisitRoots(visitor, arg);
856  class_linker_->VisitRoots(visitor, arg);
857  intern_table_->VisitRoots(visitor, arg);
858  java_vm_->VisitRoots(visitor, arg);
859  thread_list_->VisitRoots(visitor, arg);
860  visitor(jni_stub_array_, arg);
861  visitor(abstract_method_error_stub_array_, arg);
862  for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
863    visitor(resolution_stub_array_[i], arg);
864  }
865  visitor(resolution_method_, arg);
866  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
867    visitor(callee_save_method_[i], arg);
868  }
869}
870
871bool Runtime::HasJniDlsymLookupStub() const {
872  return jni_stub_array_ != NULL;
873}
874
875ByteArray* Runtime::GetJniDlsymLookupStub() const {
876  CHECK(jni_stub_array_ != NULL);
877  return jni_stub_array_;
878}
879
880void Runtime::SetJniDlsymLookupStub(ByteArray* jni_stub_array) {
881  CHECK(jni_stub_array != NULL)  << " jni_stub_array=" << jni_stub_array;
882  CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array)
883      << "jni_stub_array_=" << jni_stub_array_ << " jni_stub_array=" << jni_stub_array;
884  jni_stub_array_ = jni_stub_array;
885}
886
887bool Runtime::HasAbstractMethodErrorStubArray() const {
888  return abstract_method_error_stub_array_ != NULL;
889}
890
891ByteArray* Runtime::GetAbstractMethodErrorStubArray() const {
892  CHECK(abstract_method_error_stub_array_ != NULL);
893  return abstract_method_error_stub_array_;
894}
895
896void Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) {
897  CHECK(abstract_method_error_stub_array != NULL);
898  CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array);
899  abstract_method_error_stub_array_ = abstract_method_error_stub_array;
900}
901
902
903Runtime::TrampolineType Runtime::GetTrampolineType(Method* method) {
904  if (method == NULL) {
905    return Runtime::kUnknownMethod;
906  } else if (method->IsStatic()) {
907    return Runtime::kStaticMethod;
908  } else {
909    return Runtime::kUnknownMethod;
910  }
911}
912
913bool Runtime::HasResolutionStubArray(TrampolineType type) const {
914  return resolution_stub_array_[type] != NULL;
915}
916
917ByteArray* Runtime::GetResolutionStubArray(TrampolineType type) const {
918  CHECK(HasResolutionStubArray(type));
919  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType));
920  return resolution_stub_array_[type];
921}
922
923void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) {
924  CHECK(resolution_stub_array != NULL);
925  CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array);
926  resolution_stub_array_[type] = resolution_stub_array;
927}
928
929Method* Runtime::CreateResolutionMethod() {
930  Class* method_class = Method::GetMethodClass();
931  SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject()));
932  method->SetDeclaringClass(method_class);
933  // TODO: use a special method for resolution method saves
934  method->SetDexMethodIndex(DexFile::kDexNoIndex16);
935  ByteArray* unknown_resolution_stub = GetResolutionStubArray(kUnknownMethod);
936  CHECK(unknown_resolution_stub != NULL);
937  method->SetCode(unknown_resolution_stub->GetData());
938  return method.get();
939}
940
941bool Runtime::HasResolutionMethod() const {
942  return resolution_method_ != NULL;
943}
944
945// Returns a special method that calls into a trampoline for runtime method resolution
946Method* Runtime::GetResolutionMethod() const {
947  CHECK(HasResolutionMethod());
948  return resolution_method_;
949}
950
951void Runtime::SetResolutionMethod(Method* method) {
952  resolution_method_ = method;
953}
954
955Method* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type) {
956  Class* method_class = Method::GetMethodClass();
957  SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject()));
958  method->SetDeclaringClass(method_class);
959  // TODO: use a special method for callee saves
960  method->SetDexMethodIndex(DexFile::kDexNoIndex16);
961  method->SetCode(NULL);
962  if ((instruction_set == kThumb2) || (instruction_set == kArm)) {
963    uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6)  | (1 << art::arm::R7) |
964                          (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11);
965    uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3);
966    uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9);
967    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills :0) |
968                           (type == kSaveAll ? all_spills :0) | (1 << art::arm::LR);
969    uint32_t fp_all_spills = (1 << art::arm::S0)  | (1 << art::arm::S1)  | (1 << art::arm::S2) |
970                             (1 << art::arm::S3)  | (1 << art::arm::S4)  | (1 << art::arm::S5) |
971                             (1 << art::arm::S6)  | (1 << art::arm::S7)  | (1 << art::arm::S8) |
972                             (1 << art::arm::S9)  | (1 << art::arm::S10) | (1 << art::arm::S11) |
973                             (1 << art::arm::S12) | (1 << art::arm::S13) | (1 << art::arm::S14) |
974                             (1 << art::arm::S15) | (1 << art::arm::S16) | (1 << art::arm::S17) |
975                             (1 << art::arm::S18) | (1 << art::arm::S19) | (1 << art::arm::S20) |
976                             (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) |
977                             (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) |
978                             (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) |
979                             (1 << art::arm::S30) | (1 << art::arm::S31);
980    uint32_t fp_spills = type == kSaveAll ? fp_all_spills : 0;
981    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
982                                 __builtin_popcount(fp_spills) /* fprs */ +
983                                 1 /* Method* */) * kPointerSize, kStackAlignment);
984    method->SetFrameSizeInBytes(frame_size);
985    method->SetCoreSpillMask(core_spills);
986    method->SetFpSpillMask(fp_spills);
987  } else if (instruction_set == kX86) {
988    uint32_t ref_spills = (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI);
989    uint32_t arg_spills = (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX);
990    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) |
991                         (1 << art::x86::kNumberOfCpuRegisters);  // fake return address callee save
992    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
993                                 1 /* Method* */) * kPointerSize, kStackAlignment);
994    method->SetFrameSizeInBytes(frame_size);
995    method->SetCoreSpillMask(core_spills);
996    method->SetFpSpillMask(0);
997  } else {
998    UNIMPLEMENTED(FATAL);
999  }
1000  return method.get();
1001}
1002
1003bool Runtime::HasCalleeSaveMethod(CalleeSaveType type) const {
1004  return callee_save_method_[type] != NULL;
1005}
1006
1007// Returns a special method that describes all callee saves being spilled to the stack.
1008Method* Runtime::GetCalleeSaveMethod(CalleeSaveType type) const {
1009  CHECK(HasCalleeSaveMethod(type));
1010  return callee_save_method_[type];
1011}
1012
1013void Runtime::SetCalleeSaveMethod(Method* method, CalleeSaveType type) {
1014  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
1015  callee_save_method_[type] = method;
1016}
1017
1018void Runtime::EnableMethodTracing(Trace* tracer) {
1019  CHECK(!IsMethodTracingActive());
1020  tracer_ = tracer;
1021}
1022
1023void Runtime::DisableMethodTracing() {
1024  CHECK(IsMethodTracingActive());
1025  delete tracer_;
1026  tracer_ = NULL;
1027}
1028
1029bool Runtime::IsMethodTracingActive() const {
1030  return (tracer_ != NULL);
1031}
1032
1033Trace* Runtime::GetTracer() const {
1034  CHECK(IsMethodTracingActive());
1035  return tracer_;
1036}
1037
1038const std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(const ClassLoader* class_loader) {
1039  if (class_loader == NULL) {
1040    return GetClassLinker()->GetBootClassPath();
1041  }
1042  CHECK(UseCompileTimeClassPath());
1043  CompileTimeClassPaths::const_iterator it = compile_time_class_paths_.find(class_loader);
1044  CHECK(it != compile_time_class_paths_.end());
1045  return it->second;
1046}
1047
1048void Runtime::SetCompileTimeClassPath(const ClassLoader* class_loader, std::vector<const DexFile*>& class_path) {
1049  CHECK(!IsStarted());
1050  use_compile_time_class_path_ = true;
1051  compile_time_class_paths_.Put(class_loader, class_path);
1052}
1053
1054}  // namespace art
1055