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