runtime.cc revision d2fe10a3a34af171bf1631219cd2d6ff6b7778b5
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// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
20#include <sys/mount.h>
21#include <linux/fs.h>
22
23#include <signal.h>
24#include <sys/syscall.h>
25
26#include <cstdio>
27#include <cstdlib>
28#include <limits>
29#include <vector>
30
31#include "arch/arm/registers_arm.h"
32#include "arch/mips/registers_mips.h"
33#include "arch/x86/registers_x86.h"
34#include "arch/x86_64/registers_x86_64.h"
35#include "atomic.h"
36#include "class_linker.h"
37#include "debugger.h"
38#include "gc/accounting/card_table-inl.h"
39#include "gc/heap.h"
40#include "gc/space/space.h"
41#include "image.h"
42#include "instrumentation.h"
43#include "intern_table.h"
44#include "invoke_arg_array_builder.h"
45#include "jni_internal.h"
46#include "mirror/art_field-inl.h"
47#include "mirror/art_method-inl.h"
48#include "mirror/array.h"
49#include "mirror/class-inl.h"
50#include "mirror/class_loader.h"
51#include "mirror/stack_trace_element.h"
52#include "mirror/throwable.h"
53#include "monitor.h"
54#include "oat_file.h"
55#include "ScopedLocalRef.h"
56#include "scoped_thread_state_change.h"
57#include "signal_catcher.h"
58#include "signal_set.h"
59#include "sirt_ref.h"
60#include "thread.h"
61#include "thread_list.h"
62#include "trace.h"
63#include "transaction.h"
64#include "profiler.h"
65#include "UniquePtr.h"
66#include "verifier/method_verifier.h"
67#include "well_known_classes.h"
68
69#include "JniConstants.h"  // Last to avoid LOG redefinition in ics-mr1-plus-art.
70
71namespace art {
72
73Runtime* Runtime::instance_ = NULL;
74
75Runtime::Runtime()
76    : compiler_callbacks_(nullptr),
77      is_zygote_(false),
78      is_concurrent_gc_enabled_(true),
79      is_explicit_gc_disabled_(false),
80      compiler_filter_(kSpeed),
81      huge_method_threshold_(0),
82      large_method_threshold_(0),
83      small_method_threshold_(0),
84      tiny_method_threshold_(0),
85      num_dex_methods_threshold_(0),
86      sea_ir_mode_(false),
87      default_stack_size_(0),
88      heap_(nullptr),
89      max_spins_before_thin_lock_inflation_(Monitor::kDefaultMaxSpinsBeforeThinLockInflation),
90      monitor_list_(nullptr),
91      monitor_pool_(nullptr),
92      thread_list_(nullptr),
93      intern_table_(nullptr),
94      class_linker_(nullptr),
95      signal_catcher_(nullptr),
96      java_vm_(nullptr),
97      pre_allocated_OutOfMemoryError_(nullptr),
98      resolution_method_(nullptr),
99      imt_conflict_method_(nullptr),
100      default_imt_(nullptr),
101      method_verifiers_lock_("Method verifiers lock"),
102      threads_being_born_(0),
103      shutdown_cond_(new ConditionVariable("Runtime shutdown", *Locks::runtime_shutdown_lock_)),
104      shutting_down_(false),
105      shutting_down_started_(false),
106      started_(false),
107      finished_starting_(false),
108      vfprintf_(nullptr),
109      exit_(nullptr),
110      abort_(nullptr),
111      stats_enabled_(false),
112      profile_(false),
113      profile_period_s_(0),
114      profile_duration_s_(0),
115      profile_interval_us_(0),
116      profile_backoff_coefficient_(0),
117      method_trace_(false),
118      method_trace_file_size_(0),
119      instrumentation_(),
120      use_compile_time_class_path_(false),
121      main_thread_group_(nullptr),
122      system_thread_group_(nullptr),
123      system_class_loader_(nullptr),
124      dump_gc_performance_on_shutdown_(false),
125      preinitialization_transaction(nullptr) {
126  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
127    callee_save_methods_[i] = nullptr;
128  }
129}
130
131Runtime::~Runtime() {
132  if (dump_gc_performance_on_shutdown_) {
133    // This can't be called from the Heap destructor below because it
134    // could call RosAlloc::InspectAll() which needs the thread_list
135    // to be still alive.
136    heap_->DumpGcPerformanceInfo(LOG(INFO));
137  }
138
139  Thread* self = Thread::Current();
140  {
141    MutexLock mu(self, *Locks::runtime_shutdown_lock_);
142    shutting_down_started_ = true;
143    while (threads_being_born_ > 0) {
144      shutdown_cond_->Wait(self);
145    }
146    shutting_down_ = true;
147  }
148  Trace::Shutdown();
149
150  // Make sure to let the GC complete if it is running.
151  heap_->WaitForGcToComplete(self);
152  heap_->DeleteThreadPool();
153
154  // Make sure our internal threads are dead before we start tearing down things they're using.
155  Dbg::StopJdwp();
156  delete signal_catcher_;
157
158  // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended.
159  delete thread_list_;
160  delete monitor_list_;
161  delete monitor_pool_;
162  delete class_linker_;
163  delete heap_;
164  delete intern_table_;
165  delete java_vm_;
166  Thread::Shutdown();
167  QuasiAtomic::Shutdown();
168  verifier::MethodVerifier::Shutdown();
169  // TODO: acquire a static mutex on Runtime to avoid racing.
170  CHECK(instance_ == nullptr || instance_ == this);
171  instance_ = nullptr;
172}
173
174struct AbortState {
175  void Dump(std::ostream& os) {
176    if (gAborting > 1) {
177      os << "Runtime aborting --- recursively, so no thread-specific detail!\n";
178      return;
179    }
180    gAborting++;
181    os << "Runtime aborting...\n";
182    if (Runtime::Current() == NULL) {
183      os << "(Runtime does not yet exist!)\n";
184      return;
185    }
186    Thread* self = Thread::Current();
187    if (self == NULL) {
188      os << "(Aborting thread was not attached to runtime!)\n";
189    } else {
190      // TODO: we're aborting and the ScopedObjectAccess may attempt to acquire the mutator_lock_
191      //       which may block indefinitely if there's a misbehaving thread holding it exclusively.
192      //       The code below should be made robust to this.
193      ScopedObjectAccess soa(self);
194      os << "Aborting thread:\n";
195      self->Dump(os);
196      if (self->IsExceptionPending()) {
197        ThrowLocation throw_location;
198        mirror::Throwable* exception = self->GetException(&throw_location);
199        os << "Pending exception " << PrettyTypeOf(exception)
200            << " thrown by '" << throw_location.Dump() << "'\n"
201            << exception->Dump();
202      }
203    }
204    DumpAllThreads(os, self);
205  }
206
207  void DumpAllThreads(std::ostream& os, Thread* self) NO_THREAD_SAFETY_ANALYSIS {
208    bool tll_already_held = Locks::thread_list_lock_->IsExclusiveHeld(self);
209    bool ml_already_held = Locks::mutator_lock_->IsSharedHeld(self);
210    if (!tll_already_held || !ml_already_held) {
211      os << "Dumping all threads without appropriate locks held:"
212          << (!tll_already_held ? " thread list lock" : "")
213          << (!ml_already_held ? " mutator lock" : "")
214          << "\n";
215    }
216    os << "All threads:\n";
217    Runtime::Current()->GetThreadList()->DumpLocked(os);
218  }
219};
220
221void Runtime::Abort() {
222  gAborting++;  // set before taking any locks
223
224  // Ensure that we don't have multiple threads trying to abort at once,
225  // which would result in significantly worse diagnostics.
226  MutexLock mu(Thread::Current(), *Locks::abort_lock_);
227
228  // Get any pending output out of the way.
229  fflush(NULL);
230
231  // Many people have difficulty distinguish aborts from crashes,
232  // so be explicit.
233  AbortState state;
234  LOG(INTERNAL_FATAL) << Dumpable<AbortState>(state);
235
236  // Call the abort hook if we have one.
237  if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) {
238    LOG(INTERNAL_FATAL) << "Calling abort hook...";
239    Runtime::Current()->abort_();
240    // notreached
241    LOG(INTERNAL_FATAL) << "Unexpectedly returned from abort hook!";
242  }
243
244#if defined(__GLIBC__)
245  // TODO: we ought to be able to use pthread_kill(3) here (or abort(3),
246  // which POSIX defines in terms of raise(3), which POSIX defines in terms
247  // of pthread_kill(3)). On Linux, though, libcorkscrew can't unwind through
248  // libpthread, which means the stacks we dump would be useless. Calling
249  // tgkill(2) directly avoids that.
250  syscall(__NR_tgkill, getpid(), GetTid(), SIGABRT);
251  // TODO: LLVM installs it's own SIGABRT handler so exit to be safe... Can we disable that in LLVM?
252  // If not, we could use sigaction(3) before calling tgkill(2) and lose this call to exit(3).
253  exit(1);
254#else
255  abort();
256#endif
257  // notreached
258}
259
260bool Runtime::PreZygoteFork() {
261  heap_->PreZygoteFork();
262  return true;
263}
264
265void Runtime::CallExitHook(jint status) {
266  if (exit_ != NULL) {
267    ScopedThreadStateChange tsc(Thread::Current(), kNative);
268    exit_(status);
269    LOG(WARNING) << "Exit hook returned instead of exiting!";
270  }
271}
272
273// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify
274// memory sizes.  [kK] indicates kilobytes, [mM] megabytes, and
275// [gG] gigabytes.
276//
277// "s" should point just past the "-Xm?" part of the string.
278// "div" specifies a divisor, e.g. 1024 if the value must be a multiple
279// of 1024.
280//
281// The spec says the -Xmx and -Xms options must be multiples of 1024.  It
282// doesn't say anything about -Xss.
283//
284// Returns 0 (a useless size) if "s" is malformed or specifies a low or
285// non-evenly-divisible value.
286//
287size_t ParseMemoryOption(const char* s, size_t div) {
288  // strtoul accepts a leading [+-], which we don't want,
289  // so make sure our string starts with a decimal digit.
290  if (isdigit(*s)) {
291    char* s2;
292    size_t val = strtoul(s, &s2, 10);
293    if (s2 != s) {
294      // s2 should be pointing just after the number.
295      // If this is the end of the string, the user
296      // has specified a number of bytes.  Otherwise,
297      // there should be exactly one more character
298      // that specifies a multiplier.
299      if (*s2 != '\0') {
300        // The remainder of the string is either a single multiplier
301        // character, or nothing to indicate that the value is in
302        // bytes.
303        char c = *s2++;
304        if (*s2 == '\0') {
305          size_t mul;
306          if (c == '\0') {
307            mul = 1;
308          } else if (c == 'k' || c == 'K') {
309            mul = KB;
310          } else if (c == 'm' || c == 'M') {
311            mul = MB;
312          } else if (c == 'g' || c == 'G') {
313            mul = GB;
314          } else {
315            // Unknown multiplier character.
316            return 0;
317          }
318
319          if (val <= std::numeric_limits<size_t>::max() / mul) {
320            val *= mul;
321          } else {
322            // Clamp to a multiple of 1024.
323            val = std::numeric_limits<size_t>::max() & ~(1024-1);
324          }
325        } else {
326          // There's more than one character after the numeric part.
327          return 0;
328        }
329      }
330      // The man page says that a -Xm value must be a multiple of 1024.
331      if (val % div == 0) {
332        return val;
333      }
334    }
335  }
336  return 0;
337}
338
339static const std::string StringAfterChar(const std::string& s, char c) {
340  std::string::size_type colon = s.find(c);
341  if (colon == std::string::npos) {
342    LOG(FATAL) << "Missing char " << c << " in string " << s;
343  }
344  // Add one to remove the char we were trimming until.
345  return s.substr(colon + 1);
346}
347
348static size_t ParseIntegerOrDie(const std::string& s, char after_char) {
349  std::string::size_type colon = s.find(after_char);
350  if (colon == std::string::npos) {
351    LOG(FATAL) << "Missing char " << after_char << " in string " << s;
352  }
353  const char* begin = &s[colon + 1];
354  char* end;
355  size_t result = strtoul(begin, &end, 10);
356  if (begin == end || *end != '\0') {
357    LOG(FATAL) << "Failed to parse integer in: " << s;
358  }
359  return result;
360}
361
362
363static double ParseDoubleOrDie(const std::string& option, char after_char, double min, double max,
364                               bool ignore_unrecognized, double defval) {
365  std::istringstream iss(StringAfterChar(option, after_char));
366  double value;
367  iss >> value;
368  // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
369  const bool sane_val = iss.eof() && (value >= min) && (value <= max);
370  if (!sane_val) {
371    if (ignore_unrecognized) {
372      return defval;
373    }
374    LOG(FATAL)<< "Invalid option '" << option << "'";
375    return defval;
376  }
377  return value;
378}
379
380void Runtime::SweepSystemWeaks(IsMarkedCallback* visitor, void* arg) {
381  GetInternTable()->SweepInternTableWeaks(visitor, arg);
382  GetMonitorList()->SweepMonitorList(visitor, arg);
383  GetJavaVM()->SweepJniWeakGlobals(visitor, arg);
384  Dbg::UpdateObjectPointers(visitor, arg);
385}
386
387static gc::CollectorType ParseCollectorType(const std::string& option) {
388  if (option == "MS" || option == "nonconcurrent") {
389    return gc::kCollectorTypeMS;
390  } else if (option == "CMS" || option == "concurrent") {
391    return gc::kCollectorTypeCMS;
392  } else if (option == "SS") {
393    return gc::kCollectorTypeSS;
394  } else if (option == "GSS") {
395    return gc::kCollectorTypeGSS;
396  } else {
397    return gc::kCollectorTypeNone;
398  }
399}
400
401Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) {
402  UniquePtr<ParsedOptions> parsed(new ParsedOptions());
403  const char* boot_class_path_string = getenv("BOOTCLASSPATH");
404  if (boot_class_path_string != NULL) {
405    parsed->boot_class_path_string_ = boot_class_path_string;
406  }
407  const char* class_path_string = getenv("CLASSPATH");
408  if (class_path_string != NULL) {
409    parsed->class_path_string_ = class_path_string;
410  }
411  // -Xcheck:jni is off by default for regular builds but on by default in debug builds.
412  parsed->check_jni_ = kIsDebugBuild;
413
414  parsed->heap_initial_size_ = gc::Heap::kDefaultInitialSize;
415  parsed->heap_maximum_size_ = gc::Heap::kDefaultMaximumSize;
416  parsed->heap_min_free_ = gc::Heap::kDefaultMinFree;
417  parsed->heap_max_free_ = gc::Heap::kDefaultMaxFree;
418  parsed->heap_target_utilization_ = gc::Heap::kDefaultTargetUtilization;
419  parsed->heap_growth_limit_ = 0;  // 0 means no growth limit .
420  // Default to number of processors minus one since the main GC thread also does work.
421  parsed->parallel_gc_threads_ = sysconf(_SC_NPROCESSORS_CONF) - 1;
422  // Only the main GC thread, no workers.
423  parsed->conc_gc_threads_ = 0;
424  // Default is CMS which is Sticky + Partial + Full CMS GC.
425  parsed->collector_type_ = gc::kCollectorTypeCMS;
426  // If background_collector_type_ is kCollectorTypeNone, it defaults to the collector_type_ after
427  // parsing options.
428  parsed->background_collector_type_ = gc::kCollectorTypeNone;
429  parsed->stack_size_ = 0;  // 0 means default.
430  parsed->max_spins_before_thin_lock_inflation_ = Monitor::kDefaultMaxSpinsBeforeThinLockInflation;
431  parsed->low_memory_mode_ = false;
432  parsed->use_tlab_ = false;
433  parsed->verify_pre_gc_heap_ = false;
434  parsed->verify_post_gc_heap_ = kIsDebugBuild;
435  parsed->verify_pre_gc_rosalloc_ = kIsDebugBuild;
436  parsed->verify_post_gc_rosalloc_ = false;
437
438  parsed->compiler_callbacks_ = nullptr;
439  parsed->is_zygote_ = false;
440  parsed->interpreter_only_ = false;
441  parsed->is_explicit_gc_disabled_ = false;
442
443  parsed->long_pause_log_threshold_ = gc::Heap::kDefaultLongPauseLogThreshold;
444  parsed->long_gc_log_threshold_ = gc::Heap::kDefaultLongGCLogThreshold;
445  parsed->dump_gc_performance_on_shutdown_ = false;
446  parsed->ignore_max_footprint_ = false;
447
448  parsed->lock_profiling_threshold_ = 0;
449  parsed->hook_is_sensitive_thread_ = NULL;
450
451  parsed->hook_vfprintf_ = vfprintf;
452  parsed->hook_exit_ = exit;
453  parsed->hook_abort_ = NULL;  // We don't call abort(3) by default; see Runtime::Abort.
454
455  parsed->compiler_filter_ = Runtime::kDefaultCompilerFilter;
456  parsed->huge_method_threshold_ = Runtime::kDefaultHugeMethodThreshold;
457  parsed->large_method_threshold_ = Runtime::kDefaultLargeMethodThreshold;
458  parsed->small_method_threshold_ = Runtime::kDefaultSmallMethodThreshold;
459  parsed->tiny_method_threshold_ = Runtime::kDefaultTinyMethodThreshold;
460  parsed->num_dex_methods_threshold_ = Runtime::kDefaultNumDexMethodsThreshold;
461
462  parsed->sea_ir_mode_ = false;
463//  gLogVerbosity.class_linker = true;  // TODO: don't check this in!
464//  gLogVerbosity.compiler = true;  // TODO: don't check this in!
465//  gLogVerbosity.verifier = true;  // TODO: don't check this in!
466//  gLogVerbosity.heap = true;  // TODO: don't check this in!
467//  gLogVerbosity.gc = true;  // TODO: don't check this in!
468//  gLogVerbosity.jdwp = true;  // TODO: don't check this in!
469//  gLogVerbosity.jni = true;  // TODO: don't check this in!
470//  gLogVerbosity.monitor = true;  // TODO: don't check this in!
471//  gLogVerbosity.startup = true;  // TODO: don't check this in!
472//  gLogVerbosity.third_party_jni = true;  // TODO: don't check this in!
473//  gLogVerbosity.threads = true;  // TODO: don't check this in!
474
475  parsed->method_trace_ = false;
476  parsed->method_trace_file_ = "/data/method-trace-file.bin";
477  parsed->method_trace_file_size_ = 10 * MB;
478
479  parsed->profile_ = false;
480  parsed->profile_period_s_ = 10;           // Seconds.
481  parsed->profile_duration_s_ = 20;          // Seconds.
482  parsed->profile_interval_us_ = 500;       // Microseconds.
483  parsed->profile_backoff_coefficient_ = 2.0;
484
485  for (size_t i = 0; i < options.size(); ++i) {
486    const std::string option(options[i].first);
487    if (true && options[0].first == "-Xzygote") {
488      LOG(INFO) << "option[" << i << "]=" << option;
489    }
490    if (StartsWith(option, "-Xbootclasspath:")) {
491      parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data();
492    } else if (option == "-classpath" || option == "-cp") {
493      // TODO: support -Djava.class.path
494      i++;
495      if (i == options.size()) {
496        // TODO: usage
497        LOG(FATAL) << "Missing required class path value for " << option;
498        return NULL;
499      }
500      const StringPiece& value = options[i].first;
501      parsed->class_path_string_ = value.data();
502    } else if (option == "bootclasspath") {
503      parsed->boot_class_path_
504          = reinterpret_cast<const std::vector<const DexFile*>*>(options[i].second);
505    } else if (StartsWith(option, "-Ximage:")) {
506      parsed->image_ = StringAfterChar(option, ':');
507    } else if (StartsWith(option, "-Xcheck:jni")) {
508      parsed->check_jni_ = true;
509    } else if (StartsWith(option, "-Xrunjdwp:") || StartsWith(option, "-agentlib:jdwp=")) {
510      std::string tail(option.substr(option[1] == 'X' ? 10 : 15));
511      if (tail == "help" || !Dbg::ParseJdwpOptions(tail)) {
512        LOG(FATAL) << "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n"
513                   << "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n";
514        return NULL;
515      }
516    } else if (StartsWith(option, "-Xms")) {
517      size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).c_str(), 1024);
518      if (size == 0) {
519        if (ignore_unrecognized) {
520          continue;
521        }
522        // TODO: usage
523        LOG(FATAL) << "Failed to parse " << option;
524        return NULL;
525      }
526      parsed->heap_initial_size_ = size;
527    } else if (StartsWith(option, "-Xmx")) {
528      size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).c_str(), 1024);
529      if (size == 0) {
530        if (ignore_unrecognized) {
531          continue;
532        }
533        // TODO: usage
534        LOG(FATAL) << "Failed to parse " << option;
535        return NULL;
536      }
537      parsed->heap_maximum_size_ = size;
538    } else if (StartsWith(option, "-XX:HeapGrowthLimit=")) {
539      size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapGrowthLimit=")).c_str(), 1024);
540      if (size == 0) {
541        if (ignore_unrecognized) {
542          continue;
543        }
544        // TODO: usage
545        LOG(FATAL) << "Failed to parse " << option;
546        return NULL;
547      }
548      parsed->heap_growth_limit_ = size;
549    } else if (StartsWith(option, "-XX:HeapMinFree=")) {
550      size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapMinFree=")).c_str(), 1024);
551      if (size == 0) {
552        if (ignore_unrecognized) {
553          continue;
554        }
555        // TODO: usage
556        LOG(FATAL) << "Failed to parse " << option;
557        return NULL;
558      }
559      parsed->heap_min_free_ = size;
560    } else if (StartsWith(option, "-XX:HeapMaxFree=")) {
561      size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapMaxFree=")).c_str(), 1024);
562      if (size == 0) {
563        if (ignore_unrecognized) {
564          continue;
565        }
566        // TODO: usage
567        LOG(FATAL) << "Failed to parse " << option;
568        return NULL;
569      }
570      parsed->heap_max_free_ = size;
571    } else if (StartsWith(option, "-XX:HeapTargetUtilization=")) {
572      parsed->heap_target_utilization_ = ParseDoubleOrDie(
573          option, '=', 0.1, 0.9, ignore_unrecognized, parsed->heap_target_utilization_);
574    } else if (StartsWith(option, "-XX:ParallelGCThreads=")) {
575      parsed->parallel_gc_threads_ = ParseIntegerOrDie(option, '=');
576    } else if (StartsWith(option, "-XX:ConcGCThreads=")) {
577      parsed->conc_gc_threads_ = ParseIntegerOrDie(option, '=');
578    } else if (StartsWith(option, "-Xss")) {
579      size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).c_str(), 1);
580      if (size == 0) {
581        if (ignore_unrecognized) {
582          continue;
583        }
584        // TODO: usage
585        LOG(FATAL) << "Failed to parse " << option;
586        return NULL;
587      }
588      parsed->stack_size_ = size;
589    } else if (StartsWith(option, "-XX:MaxSpinsBeforeThinLockInflation=")) {
590      parsed->max_spins_before_thin_lock_inflation_ = ParseIntegerOrDie(option, '=');
591    } else if (StartsWith(option, "-XX:LongPauseLogThreshold=")) {
592      parsed->long_pause_log_threshold_ = MsToNs(ParseIntegerOrDie(option, '='));
593    } else if (StartsWith(option, "-XX:LongGCLogThreshold=")) {
594      parsed->long_gc_log_threshold_ = MsToNs(ParseIntegerOrDie(option, '='));
595    } else if (option == "-XX:DumpGCPerformanceOnShutdown") {
596      parsed->dump_gc_performance_on_shutdown_ = true;
597    } else if (option == "-XX:IgnoreMaxFootprint") {
598      parsed->ignore_max_footprint_ = true;
599    } else if (option == "-XX:LowMemoryMode") {
600      parsed->low_memory_mode_ = true;
601    } else if (option == "-XX:UseTLAB") {
602      parsed->use_tlab_ = true;
603    } else if (StartsWith(option, "-D")) {
604      parsed->properties_.push_back(option.substr(strlen("-D")));
605    } else if (StartsWith(option, "-Xjnitrace:")) {
606      parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:"));
607    } else if (option == "compilercallbacks") {
608      parsed->compiler_callbacks_ =
609          reinterpret_cast<CompilerCallbacks*>(const_cast<void*>(options[i].second));
610    } else if (option == "-Xzygote") {
611      parsed->is_zygote_ = true;
612    } else if (option == "-Xint") {
613      parsed->interpreter_only_ = true;
614    } else if (StartsWith(option, "-Xgc:")) {
615      std::vector<std::string> gc_options;
616      Split(option.substr(strlen("-Xgc:")), ',', gc_options);
617      for (const std::string& gc_option : gc_options) {
618        gc::CollectorType collector_type = ParseCollectorType(gc_option);
619        if (collector_type != gc::kCollectorTypeNone) {
620          parsed->collector_type_ = collector_type;
621        } else if (gc_option == "preverify") {
622          parsed->verify_pre_gc_heap_ = true;
623        } else if (gc_option == "nopreverify") {
624          parsed->verify_pre_gc_heap_ = false;
625        }  else if (gc_option == "postverify") {
626          parsed->verify_post_gc_heap_ = true;
627        } else if (gc_option == "nopostverify") {
628          parsed->verify_post_gc_heap_ = false;
629        } else if (gc_option == "preverify_rosalloc") {
630          parsed->verify_pre_gc_rosalloc_ = true;
631        } else if (gc_option == "nopreverify_rosalloc") {
632          parsed->verify_pre_gc_rosalloc_ = false;
633        } else if (gc_option == "postverify_rosalloc") {
634          parsed->verify_post_gc_rosalloc_ = true;
635        } else if (gc_option == "nopostverify_rosalloc") {
636          parsed->verify_post_gc_rosalloc_ = false;
637        } else {
638          LOG(WARNING) << "Ignoring unknown -Xgc option: " << gc_option;
639        }
640      }
641    } else if (StartsWith(option, "-XX:BackgroundGC=")) {
642      const std::string substring = StringAfterChar(option, '=');
643      gc::CollectorType collector_type = ParseCollectorType(substring);
644      if (collector_type != gc::kCollectorTypeNone) {
645        parsed->background_collector_type_ = collector_type;
646      } else {
647        LOG(WARNING) << "Ignoring unknown -XX:BackgroundGC option: " << substring;
648      }
649    } else if (option == "-XX:+DisableExplicitGC") {
650      parsed->is_explicit_gc_disabled_ = true;
651    } else if (StartsWith(option, "-verbose:")) {
652      std::vector<std::string> verbose_options;
653      Split(option.substr(strlen("-verbose:")), ',', verbose_options);
654      for (size_t i = 0; i < verbose_options.size(); ++i) {
655        if (verbose_options[i] == "class") {
656          gLogVerbosity.class_linker = true;
657        } else if (verbose_options[i] == "verifier") {
658          gLogVerbosity.verifier = true;
659        } else if (verbose_options[i] == "compiler") {
660          gLogVerbosity.compiler = true;
661        } else if (verbose_options[i] == "heap") {
662          gLogVerbosity.heap = true;
663        } else if (verbose_options[i] == "gc") {
664          gLogVerbosity.gc = true;
665        } else if (verbose_options[i] == "jdwp") {
666          gLogVerbosity.jdwp = true;
667        } else if (verbose_options[i] == "jni") {
668          gLogVerbosity.jni = true;
669        } else if (verbose_options[i] == "monitor") {
670          gLogVerbosity.monitor = true;
671        } else if (verbose_options[i] == "startup") {
672          gLogVerbosity.startup = true;
673        } else if (verbose_options[i] == "third-party-jni") {
674          gLogVerbosity.third_party_jni = true;
675        } else if (verbose_options[i] == "threads") {
676          gLogVerbosity.threads = true;
677        } else {
678          LOG(WARNING) << "Ignoring unknown -verbose option: " << verbose_options[i];
679        }
680      }
681    } else if (StartsWith(option, "-Xjnigreflimit:")) {
682      // Silently ignored for backwards compatibility.
683    } else if (StartsWith(option, "-Xlockprofthreshold:")) {
684      parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option, ':');
685    } else if (StartsWith(option, "-Xstacktracefile:")) {
686      parsed->stack_trace_file_ = StringAfterChar(option, ':');
687    } else if (option == "sensitiveThread") {
688      parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(const_cast<void*>(options[i].second));
689    } else if (option == "vfprintf") {
690      parsed->hook_vfprintf_ =
691          reinterpret_cast<int (*)(FILE *, const char*, va_list)>(const_cast<void*>(options[i].second));
692    } else if (option == "exit") {
693      parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(const_cast<void*>(options[i].second));
694    } else if (option == "abort") {
695      parsed->hook_abort_ = reinterpret_cast<void(*)()>(const_cast<void*>(options[i].second));
696    } else if (option == "host-prefix") {
697      parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second);
698    } else if (option == "-Xgenregmap" || option == "-Xgc:precise") {
699      // We silently ignore these for backwards compatibility.
700    } else if (option == "-Xmethod-trace") {
701      parsed->method_trace_ = true;
702    } else if (StartsWith(option, "-Xmethod-trace-file:")) {
703      parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:"));
704    } else if (StartsWith(option, "-Xmethod-trace-file-size:")) {
705      parsed->method_trace_file_size_ = ParseIntegerOrDie(option, ':');
706    } else if (option == "-Xprofile:threadcpuclock") {
707      Trace::SetDefaultClockSource(kProfilerClockSourceThreadCpu);
708    } else if (option == "-Xprofile:wallclock") {
709      Trace::SetDefaultClockSource(kProfilerClockSourceWall);
710    } else if (option == "-Xprofile:dualclock") {
711      Trace::SetDefaultClockSource(kProfilerClockSourceDual);
712    } else if (StartsWith(option, "-Xprofile:")) {
713      parsed->profile_output_filename_ = StringAfterChar(option, ';');
714      parsed->profile_ = true;
715    } else if (StartsWith(option, "-Xprofile-period:")) {
716      parsed->profile_period_s_ = ParseIntegerOrDie(option, ':');
717    } else if (StartsWith(option, "-Xprofile-duration:")) {
718      parsed->profile_duration_s_ = ParseIntegerOrDie(option, ':');
719    } else if (StartsWith(option, "-Xprofile-interval:")) {
720      parsed->profile_interval_us_ = ParseIntegerOrDie(option, ':');
721    } else if (StartsWith(option, "-Xprofile-backoff:")) {
722      parsed->profile_backoff_coefficient_ = ParseDoubleOrDie(
723          option, ':', 1.0, 10.0, ignore_unrecognized, parsed->profile_backoff_coefficient_);
724    } else if (option == "-compiler-filter:interpret-only") {
725      parsed->compiler_filter_ = kInterpretOnly;
726    } else if (option == "-compiler-filter:space") {
727      parsed->compiler_filter_ = kSpace;
728    } else if (option == "-compiler-filter:balanced") {
729      parsed->compiler_filter_ = kBalanced;
730    } else if (option == "-compiler-filter:speed") {
731      parsed->compiler_filter_ = kSpeed;
732    } else if (option == "-compiler-filter:everything") {
733      parsed->compiler_filter_ = kEverything;
734    } else if (option == "-sea_ir") {
735      parsed->sea_ir_mode_ = true;
736    } else if (StartsWith(option, "-huge-method-max:")) {
737      parsed->huge_method_threshold_ = ParseIntegerOrDie(option, ':');
738    } else if (StartsWith(option, "-large-method-max:")) {
739      parsed->large_method_threshold_ = ParseIntegerOrDie(option, ':');
740    } else if (StartsWith(option, "-small-method-max:")) {
741      parsed->small_method_threshold_ = ParseIntegerOrDie(option, ':');
742    } else if (StartsWith(option, "-tiny-method-max:")) {
743      parsed->tiny_method_threshold_ = ParseIntegerOrDie(option, ':');
744    } else if (StartsWith(option, "-num-dex-methods-max:")) {
745      parsed->num_dex_methods_threshold_ = ParseIntegerOrDie(option, ':');
746    } else {
747      if (!ignore_unrecognized) {
748        // TODO: print usage via vfprintf
749        LOG(ERROR) << "Unrecognized option " << option;
750        // TODO: this should exit, but for now tolerate unknown options
751        // return NULL;
752      }
753    }
754  }
755
756  // If a reference to the dalvik core.jar snuck in, replace it with
757  // the art specific version. This can happen with on device
758  // boot.art/boot.oat generation by GenerateImage which relies on the
759  // value of BOOTCLASSPATH.
760  std::string core_jar("/core.jar");
761  size_t core_jar_pos = parsed->boot_class_path_string_.find(core_jar);
762  if (core_jar_pos != std::string::npos) {
763    parsed->boot_class_path_string_.replace(core_jar_pos, core_jar.size(), "/core-libart.jar");
764  }
765
766  if (parsed->compiler_callbacks_ == nullptr && parsed->image_.empty()) {
767    parsed->image_ += GetAndroidRoot();
768    parsed->image_ += "/framework/boot.art";
769  }
770  if (parsed->heap_growth_limit_ == 0) {
771    parsed->heap_growth_limit_ = parsed->heap_maximum_size_;
772  }
773  if (parsed->background_collector_type_ == gc::kCollectorTypeNone) {
774    parsed->background_collector_type_ = parsed->collector_type_;
775  }
776  return parsed.release();
777}
778
779bool Runtime::Create(const Options& options, bool ignore_unrecognized) {
780  // TODO: acquire a static mutex on Runtime to avoid racing.
781  if (Runtime::instance_ != NULL) {
782    return false;
783  }
784  InitLogging(NULL);  // Calls Locks::Init() as a side effect.
785  instance_ = new Runtime;
786  if (!instance_->Init(options, ignore_unrecognized)) {
787    delete instance_;
788    instance_ = NULL;
789    return false;
790  }
791  return true;
792}
793
794jobject CreateSystemClassLoader() {
795  if (Runtime::Current()->UseCompileTimeClassPath()) {
796    return NULL;
797  }
798
799  ScopedObjectAccess soa(Thread::Current());
800  ClassLinker* cl = Runtime::Current()->GetClassLinker();
801
802  SirtRef<mirror::Class> class_loader_class(
803      soa.Self(), soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader));
804  CHECK(cl->EnsureInitialized(class_loader_class, true, true));
805
806  mirror::ArtMethod* getSystemClassLoader =
807      class_loader_class->FindDirectMethod("getSystemClassLoader", "()Ljava/lang/ClassLoader;");
808  CHECK(getSystemClassLoader != NULL);
809
810  JValue result;
811  ArgArray arg_array(nullptr, 0);
812  InvokeWithArgArray(soa, getSystemClassLoader, &arg_array, &result, "L");
813  SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
814                                            down_cast<mirror::ClassLoader*>(result.GetL()));
815  CHECK(class_loader.get() != nullptr);
816  JNIEnv* env = soa.Self()->GetJniEnv();
817  ScopedLocalRef<jobject> system_class_loader(env,
818                                              soa.AddLocalReference<jobject>(class_loader.get()));
819  CHECK(system_class_loader.get() != nullptr);
820
821  soa.Self()->SetClassLoaderOverride(class_loader.get());
822
823  SirtRef<mirror::Class> thread_class(soa.Self(),
824                                      soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread));
825  CHECK(cl->EnsureInitialized(thread_class, true, true));
826
827  mirror::ArtField* contextClassLoader =
828      thread_class->FindDeclaredInstanceField("contextClassLoader", "Ljava/lang/ClassLoader;");
829  CHECK(contextClassLoader != NULL);
830
831  // We can't run in a transaction yet.
832  contextClassLoader->SetObject<false>(soa.Self()->GetPeer(), class_loader.get());
833
834  return env->NewGlobalRef(system_class_loader.get());
835}
836
837bool Runtime::Start() {
838  VLOG(startup) << "Runtime::Start entering";
839
840  CHECK(host_prefix_.empty()) << host_prefix_;
841
842  // Restore main thread state to kNative as expected by native code.
843  Thread* self = Thread::Current();
844  self->TransitionFromRunnableToSuspended(kNative);
845
846  started_ = true;
847
848  // InitNativeMethods needs to be after started_ so that the classes
849  // it touches will have methods linked to the oat file if necessary.
850  InitNativeMethods();
851
852  // Initialize well known thread group values that may be accessed threads while attaching.
853  InitThreadGroups(self);
854
855  Thread::FinishStartup();
856
857  if (is_zygote_) {
858    if (!InitZygote()) {
859      return false;
860    }
861  } else {
862    DidForkFromZygote();
863  }
864
865  StartDaemonThreads();
866
867  system_class_loader_ = CreateSystemClassLoader();
868
869  self->GetJniEnv()->locals.AssertEmpty();
870
871  VLOG(startup) << "Runtime::Start exiting";
872
873  finished_starting_ = true;
874
875  if (profile_) {
876    // User has asked for a profile using -Xprofile
877    StartProfiler(profile_output_filename_.c_str(), true);
878  }
879
880  return true;
881}
882
883void Runtime::EndThreadBirth() EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) {
884  DCHECK_GT(threads_being_born_, 0U);
885  threads_being_born_--;
886  if (shutting_down_started_ && threads_being_born_ == 0) {
887    shutdown_cond_->Broadcast(Thread::Current());
888  }
889}
890
891// Do zygote-mode-only initialization.
892bool Runtime::InitZygote() {
893  // zygote goes into its own process group
894  setpgid(0, 0);
895
896  // See storage config details at http://source.android.com/tech/storage/
897  // Create private mount namespace shared by all children
898  if (unshare(CLONE_NEWNS) == -1) {
899    PLOG(WARNING) << "Failed to unshare()";
900    return false;
901  }
902
903  // Mark rootfs as being a slave so that changes from default
904  // namespace only flow into our children.
905  if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) {
906    PLOG(WARNING) << "Failed to mount() rootfs as MS_SLAVE";
907    return false;
908  }
909
910  // Create a staging tmpfs that is shared by our children; they will
911  // bind mount storage into their respective private namespaces, which
912  // are isolated from each other.
913  const char* target_base = getenv("EMULATED_STORAGE_TARGET");
914  if (target_base != NULL) {
915    if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV,
916              "uid=0,gid=1028,mode=0751") == -1) {
917      LOG(WARNING) << "Failed to mount tmpfs to " << target_base;
918      return false;
919    }
920  }
921
922  return true;
923}
924
925void Runtime::DidForkFromZygote() {
926  is_zygote_ = false;
927
928  // Create the thread pool.
929  heap_->CreateThreadPool();
930
931  StartSignalCatcher();
932
933  // Start the JDWP thread. If the command-line debugger flags specified "suspend=y",
934  // this will pause the runtime, so we probably want this to come last.
935  Dbg::StartJdwp();
936}
937
938void Runtime::StartSignalCatcher() {
939  if (!is_zygote_) {
940    signal_catcher_ = new SignalCatcher(stack_trace_file_);
941  }
942}
943
944bool Runtime::IsShuttingDown(Thread* self) {
945  MutexLock mu(self, *Locks::runtime_shutdown_lock_);
946  return IsShuttingDownLocked();
947}
948
949void Runtime::StartDaemonThreads() {
950  VLOG(startup) << "Runtime::StartDaemonThreads entering";
951
952  Thread* self = Thread::Current();
953
954  // Must be in the kNative state for calling native methods.
955  CHECK_EQ(self->GetState(), kNative);
956
957  JNIEnv* env = self->GetJniEnv();
958  env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons,
959                            WellKnownClasses::java_lang_Daemons_start);
960  if (env->ExceptionCheck()) {
961    env->ExceptionDescribe();
962    LOG(FATAL) << "Error starting java.lang.Daemons";
963  }
964
965  VLOG(startup) << "Runtime::StartDaemonThreads exiting";
966}
967
968bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
969  CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
970
971  UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized));
972  if (options.get() == NULL) {
973    LOG(ERROR) << "Failed to parse options";
974    return false;
975  }
976  VLOG(startup) << "Runtime::Init -verbose:startup enabled";
977
978  QuasiAtomic::Startup();
979
980  Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);
981
982  host_prefix_ = options->host_prefix_;
983  boot_class_path_string_ = options->boot_class_path_string_;
984  class_path_string_ = options->class_path_string_;
985  properties_ = options->properties_;
986
987  compiler_callbacks_ = options->compiler_callbacks_;
988  is_zygote_ = options->is_zygote_;
989  is_explicit_gc_disabled_ = options->is_explicit_gc_disabled_;
990
991  compiler_filter_ = options->compiler_filter_;
992  huge_method_threshold_ = options->huge_method_threshold_;
993  large_method_threshold_ = options->large_method_threshold_;
994  small_method_threshold_ = options->small_method_threshold_;
995  tiny_method_threshold_ = options->tiny_method_threshold_;
996  num_dex_methods_threshold_ = options->num_dex_methods_threshold_;
997
998  sea_ir_mode_ = options->sea_ir_mode_;
999  vfprintf_ = options->hook_vfprintf_;
1000  exit_ = options->hook_exit_;
1001  abort_ = options->hook_abort_;
1002
1003  default_stack_size_ = options->stack_size_;
1004  stack_trace_file_ = options->stack_trace_file_;
1005
1006  max_spins_before_thin_lock_inflation_ = options->max_spins_before_thin_lock_inflation_;
1007
1008  monitor_list_ = new MonitorList;
1009  monitor_pool_ = MonitorPool::Create();
1010  thread_list_ = new ThreadList;
1011  intern_table_ = new InternTable;
1012
1013
1014  if (options->interpreter_only_) {
1015    GetInstrumentation()->ForceInterpretOnly();
1016  }
1017
1018  heap_ = new gc::Heap(options->heap_initial_size_,
1019                       options->heap_growth_limit_,
1020                       options->heap_min_free_,
1021                       options->heap_max_free_,
1022                       options->heap_target_utilization_,
1023                       options->heap_maximum_size_,
1024                       options->image_,
1025                       options->collector_type_,
1026                       options->background_collector_type_,
1027                       options->parallel_gc_threads_,
1028                       options->conc_gc_threads_,
1029                       options->low_memory_mode_,
1030                       options->long_pause_log_threshold_,
1031                       options->long_gc_log_threshold_,
1032                       options->ignore_max_footprint_,
1033                       options->use_tlab_,
1034                       options->verify_pre_gc_heap_,
1035                       options->verify_post_gc_heap_,
1036                       options->verify_pre_gc_rosalloc_,
1037                       options->verify_post_gc_rosalloc_);
1038
1039  dump_gc_performance_on_shutdown_ = options->dump_gc_performance_on_shutdown_;
1040
1041  BlockSignals();
1042  InitPlatformSignalHandlers();
1043
1044  java_vm_ = new JavaVMExt(this, options.get());
1045
1046  Thread::Startup();
1047
1048  // ClassLinker needs an attached thread, but we can't fully attach a thread without creating
1049  // objects. We can't supply a thread group yet; it will be fixed later. Since we are the main
1050  // thread, we do not get a java peer.
1051  Thread* self = Thread::Attach("main", false, NULL, false);
1052  CHECK_EQ(self->thin_lock_thread_id_, ThreadList::kMainThreadId);
1053  CHECK(self != NULL);
1054
1055  // Set us to runnable so tools using a runtime can allocate and GC by default
1056  self->TransitionFromSuspendedToRunnable();
1057
1058  // Now we're attached, we can take the heap locks and validate the heap.
1059  GetHeap()->EnableObjectValidation();
1060
1061  CHECK_GE(GetHeap()->GetContinuousSpaces().size(), 1U);
1062  class_linker_ = new ClassLinker(intern_table_);
1063  if (GetHeap()->HasImageSpace()) {
1064    class_linker_->InitFromImage();
1065  } else {
1066    CHECK(options->boot_class_path_ != NULL);
1067    CHECK_NE(options->boot_class_path_->size(), 0U);
1068    class_linker_->InitFromCompiler(*options->boot_class_path_);
1069  }
1070  CHECK(class_linker_ != NULL);
1071  verifier::MethodVerifier::Init();
1072
1073  method_trace_ = options->method_trace_;
1074  method_trace_file_ = options->method_trace_file_;
1075  method_trace_file_size_ = options->method_trace_file_size_;
1076
1077  // Extract the profile options.
1078  profile_period_s_ = options->profile_period_s_;
1079  profile_duration_s_ = options->profile_duration_s_;
1080  profile_interval_us_ = options->profile_interval_us_;
1081  profile_backoff_coefficient_ = options->profile_backoff_coefficient_;
1082  profile_ = options->profile_;
1083  profile_output_filename_ = options->profile_output_filename_;
1084
1085  if (options->method_trace_) {
1086    Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0,
1087                 false, false, 0);
1088  }
1089
1090  // Pre-allocate an OutOfMemoryError for the double-OOME case.
1091  self->ThrowNewException(ThrowLocation(), "Ljava/lang/OutOfMemoryError;",
1092                          "OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available");
1093  pre_allocated_OutOfMemoryError_ = self->GetException(NULL);
1094  self->ClearException();
1095
1096  VLOG(startup) << "Runtime::Init exiting";
1097  return true;
1098}
1099
1100void Runtime::InitNativeMethods() {
1101  VLOG(startup) << "Runtime::InitNativeMethods entering";
1102  Thread* self = Thread::Current();
1103  JNIEnv* env = self->GetJniEnv();
1104
1105  // Must be in the kNative state for calling native methods (JNI_OnLoad code).
1106  CHECK_EQ(self->GetState(), kNative);
1107
1108  // First set up JniConstants, which is used by both the runtime's built-in native
1109  // methods and libcore.
1110  JniConstants::init(env);
1111  WellKnownClasses::Init(env);
1112
1113  // Then set up the native methods provided by the runtime itself.
1114  RegisterRuntimeNativeMethods(env);
1115
1116  // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad.
1117  // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's
1118  // the library that implements System.loadLibrary!
1119  {
1120    std::string mapped_name(StringPrintf(OS_SHARED_LIB_FORMAT_STR, "javacore"));
1121    std::string reason;
1122    self->TransitionFromSuspendedToRunnable();
1123    SirtRef<mirror::ClassLoader> class_loader(self, nullptr);
1124    if (!instance_->java_vm_->LoadNativeLibrary(mapped_name, class_loader, &reason)) {
1125      LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": " << reason;
1126    }
1127    self->TransitionFromRunnableToSuspended(kNative);
1128  }
1129
1130  // Initialize well known classes that may invoke runtime native methods.
1131  WellKnownClasses::LateInit(env);
1132
1133  VLOG(startup) << "Runtime::InitNativeMethods exiting";
1134}
1135
1136void Runtime::InitThreadGroups(Thread* self) {
1137  JNIEnvExt* env = self->GetJniEnv();
1138  ScopedJniEnvLocalRefState env_state(env);
1139  main_thread_group_ =
1140      env->NewGlobalRef(env->GetStaticObjectField(WellKnownClasses::java_lang_ThreadGroup,
1141                                                  WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup));
1142  CHECK(main_thread_group_ != NULL || IsCompiler());
1143  system_thread_group_ =
1144      env->NewGlobalRef(env->GetStaticObjectField(WellKnownClasses::java_lang_ThreadGroup,
1145                                                  WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup));
1146  CHECK(system_thread_group_ != NULL || IsCompiler());
1147}
1148
1149jobject Runtime::GetMainThreadGroup() const {
1150  CHECK(main_thread_group_ != NULL || IsCompiler());
1151  return main_thread_group_;
1152}
1153
1154jobject Runtime::GetSystemThreadGroup() const {
1155  CHECK(system_thread_group_ != NULL || IsCompiler());
1156  return system_thread_group_;
1157}
1158
1159jobject Runtime::GetSystemClassLoader() const {
1160  CHECK(system_class_loader_ != NULL || IsCompiler());
1161  return system_class_loader_;
1162}
1163
1164void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) {
1165#define REGISTER(FN) extern void FN(JNIEnv*); FN(env)
1166  // Register Throwable first so that registration of other native methods can throw exceptions
1167  REGISTER(register_java_lang_Throwable);
1168  REGISTER(register_dalvik_system_DexFile);
1169  REGISTER(register_dalvik_system_VMDebug);
1170  REGISTER(register_dalvik_system_VMRuntime);
1171  REGISTER(register_dalvik_system_VMStack);
1172  REGISTER(register_dalvik_system_Zygote);
1173  REGISTER(register_java_lang_Class);
1174  REGISTER(register_java_lang_DexCache);
1175  REGISTER(register_java_lang_Object);
1176  REGISTER(register_java_lang_Runtime);
1177  REGISTER(register_java_lang_String);
1178  REGISTER(register_java_lang_System);
1179  REGISTER(register_java_lang_Thread);
1180  REGISTER(register_java_lang_VMClassLoader);
1181  REGISTER(register_java_lang_reflect_Array);
1182  REGISTER(register_java_lang_reflect_Constructor);
1183  REGISTER(register_java_lang_reflect_Field);
1184  REGISTER(register_java_lang_reflect_Method);
1185  REGISTER(register_java_lang_reflect_Proxy);
1186  REGISTER(register_java_util_concurrent_atomic_AtomicLong);
1187  REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
1188  REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal);
1189  REGISTER(register_sun_misc_Unsafe);
1190#undef REGISTER
1191}
1192
1193void Runtime::DumpForSigQuit(std::ostream& os) {
1194  GetClassLinker()->DumpForSigQuit(os);
1195  GetInternTable()->DumpForSigQuit(os);
1196  GetJavaVM()->DumpForSigQuit(os);
1197  GetHeap()->DumpForSigQuit(os);
1198  os << "\n";
1199
1200  thread_list_->DumpForSigQuit(os);
1201  BaseMutex::DumpAll(os);
1202}
1203
1204void Runtime::DumpLockHolders(std::ostream& os) {
1205  uint64_t mutator_lock_owner = Locks::mutator_lock_->GetExclusiveOwnerTid();
1206  pid_t thread_list_lock_owner = GetThreadList()->GetLockOwner();
1207  pid_t classes_lock_owner = GetClassLinker()->GetClassesLockOwner();
1208  pid_t dex_lock_owner = GetClassLinker()->GetDexLockOwner();
1209  if ((thread_list_lock_owner | classes_lock_owner | dex_lock_owner) != 0) {
1210    os << "Mutator lock exclusive owner tid: " << mutator_lock_owner << "\n"
1211       << "ThreadList lock owner tid: " << thread_list_lock_owner << "\n"
1212       << "ClassLinker classes lock owner tid: " << classes_lock_owner << "\n"
1213       << "ClassLinker dex lock owner tid: " << dex_lock_owner << "\n";
1214  }
1215}
1216
1217void Runtime::SetStatsEnabled(bool new_state) {
1218  if (new_state == true) {
1219    GetStats()->Clear(~0);
1220    // TODO: wouldn't it make more sense to clear _all_ threads' stats?
1221    Thread::Current()->GetStats()->Clear(~0);
1222    GetInstrumentation()->InstrumentQuickAllocEntryPoints();
1223  } else {
1224    GetInstrumentation()->UninstrumentQuickAllocEntryPoints();
1225  }
1226  stats_enabled_ = new_state;
1227}
1228
1229void Runtime::ResetStats(int kinds) {
1230  GetStats()->Clear(kinds & 0xffff);
1231  // TODO: wouldn't it make more sense to clear _all_ threads' stats?
1232  Thread::Current()->GetStats()->Clear(kinds >> 16);
1233}
1234
1235int32_t Runtime::GetStat(int kind) {
1236  RuntimeStats* stats;
1237  if (kind < (1<<16)) {
1238    stats = GetStats();
1239  } else {
1240    stats = Thread::Current()->GetStats();
1241    kind >>= 16;
1242  }
1243  switch (kind) {
1244  case KIND_ALLOCATED_OBJECTS:
1245    return stats->allocated_objects;
1246  case KIND_ALLOCATED_BYTES:
1247    return stats->allocated_bytes;
1248  case KIND_FREED_OBJECTS:
1249    return stats->freed_objects;
1250  case KIND_FREED_BYTES:
1251    return stats->freed_bytes;
1252  case KIND_GC_INVOCATIONS:
1253    return stats->gc_for_alloc_count;
1254  case KIND_CLASS_INIT_COUNT:
1255    return stats->class_init_count;
1256  case KIND_CLASS_INIT_TIME:
1257    // Convert ns to us, reduce to 32 bits.
1258    return static_cast<int>(stats->class_init_time_ns / 1000);
1259  case KIND_EXT_ALLOCATED_OBJECTS:
1260  case KIND_EXT_ALLOCATED_BYTES:
1261  case KIND_EXT_FREED_OBJECTS:
1262  case KIND_EXT_FREED_BYTES:
1263    return 0;  // backward compatibility
1264  default:
1265    LOG(FATAL) << "Unknown statistic " << kind;
1266    return -1;  // unreachable
1267  }
1268}
1269
1270void Runtime::BlockSignals() {
1271  SignalSet signals;
1272  signals.Add(SIGPIPE);
1273  // SIGQUIT is used to dump the runtime's state (including stack traces).
1274  signals.Add(SIGQUIT);
1275  // SIGUSR1 is used to initiate a GC.
1276  signals.Add(SIGUSR1);
1277  signals.Block();
1278}
1279
1280bool Runtime::AttachCurrentThread(const char* thread_name, bool as_daemon, jobject thread_group,
1281                                  bool create_peer) {
1282  bool success = Thread::Attach(thread_name, as_daemon, thread_group, create_peer) != NULL;
1283  if (thread_name == NULL) {
1284    LOG(WARNING) << *Thread::Current() << " attached without supplying a name";
1285  }
1286  return success;
1287}
1288
1289void Runtime::DetachCurrentThread() {
1290  Thread* self = Thread::Current();
1291  if (self == NULL) {
1292    LOG(FATAL) << "attempting to detach thread that is not attached";
1293  }
1294  if (self->HasManagedStack()) {
1295    LOG(FATAL) << *Thread::Current() << " attempting to detach while still running code";
1296  }
1297  thread_list_->Unregister(self);
1298}
1299
1300  mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryError() const {
1301  if (pre_allocated_OutOfMemoryError_ == NULL) {
1302    LOG(ERROR) << "Failed to return pre-allocated OOME";
1303  }
1304  return pre_allocated_OutOfMemoryError_;
1305}
1306
1307void Runtime::VisitConcurrentRoots(RootCallback* callback, void* arg, bool only_dirty,
1308                                   bool clean_dirty) {
1309  intern_table_->VisitRoots(callback, arg, only_dirty, clean_dirty);
1310  class_linker_->VisitRoots(callback, arg, only_dirty, clean_dirty);
1311  // TODO: is it the right place ?
1312  if (preinitialization_transaction != nullptr) {
1313    preinitialization_transaction->VisitRoots(callback, arg);
1314  }
1315}
1316
1317void Runtime::VisitNonThreadRoots(RootCallback* callback, void* arg) {
1318  // Visit the classes held as static in mirror classes.
1319  mirror::ArtField::VisitRoots(callback, arg);
1320  mirror::ArtMethod::VisitRoots(callback, arg);
1321  mirror::Class::VisitRoots(callback, arg);
1322  mirror::StackTraceElement::VisitRoots(callback, arg);
1323  mirror::String::VisitRoots(callback, arg);
1324  mirror::Throwable::VisitRoots(callback, arg);
1325  // Visit all the primitive array types classes.
1326  mirror::PrimitiveArray<uint8_t>::VisitRoots(callback, arg);   // BooleanArray
1327  mirror::PrimitiveArray<int8_t>::VisitRoots(callback, arg);    // ByteArray
1328  mirror::PrimitiveArray<uint16_t>::VisitRoots(callback, arg);  // CharArray
1329  mirror::PrimitiveArray<double>::VisitRoots(callback, arg);    // DoubleArray
1330  mirror::PrimitiveArray<float>::VisitRoots(callback, arg);     // FloatArray
1331  mirror::PrimitiveArray<int32_t>::VisitRoots(callback, arg);   // IntArray
1332  mirror::PrimitiveArray<int64_t>::VisitRoots(callback, arg);   // LongArray
1333  mirror::PrimitiveArray<int16_t>::VisitRoots(callback, arg);   // ShortArray
1334  java_vm_->VisitRoots(callback, arg);
1335  if (pre_allocated_OutOfMemoryError_ != nullptr) {
1336    pre_allocated_OutOfMemoryError_ = down_cast<mirror::Throwable*>(
1337        callback(pre_allocated_OutOfMemoryError_, arg, 0, kRootVMInternal));
1338    DCHECK(pre_allocated_OutOfMemoryError_ != nullptr);
1339  }
1340  resolution_method_ = down_cast<mirror::ArtMethod*>(callback(resolution_method_, arg, 0,
1341                                                              kRootVMInternal));
1342  DCHECK(resolution_method_ != nullptr);
1343  if (HasImtConflictMethod()) {
1344    imt_conflict_method_ = down_cast<mirror::ArtMethod*>(callback(imt_conflict_method_, arg, 0,
1345                                                                  kRootVMInternal));
1346  }
1347  if (HasDefaultImt()) {
1348    default_imt_ = down_cast<mirror::ObjectArray<mirror::ArtMethod>*>(callback(default_imt_, arg,
1349                                                                               0, kRootVMInternal));
1350  }
1351
1352  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
1353    if (callee_save_methods_[i] != nullptr) {
1354      callee_save_methods_[i] = down_cast<mirror::ArtMethod*>(
1355          callback(callee_save_methods_[i], arg, 0, kRootVMInternal));
1356    }
1357  }
1358  {
1359    MutexLock mu(Thread::Current(), method_verifiers_lock_);
1360    for (verifier::MethodVerifier* verifier : method_verifiers_) {
1361      verifier->VisitRoots(callback, arg);
1362    }
1363  }
1364}
1365
1366void Runtime::VisitNonConcurrentRoots(RootCallback* callback, void* arg) {
1367  thread_list_->VisitRoots(callback, arg);
1368  VisitNonThreadRoots(callback, arg);
1369}
1370
1371void Runtime::VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) {
1372  VisitConcurrentRoots(callback, arg, only_dirty, clean_dirty);
1373  VisitNonConcurrentRoots(callback, arg);
1374}
1375
1376mirror::ObjectArray<mirror::ArtMethod>* Runtime::CreateDefaultImt(ClassLinker* cl) {
1377  Thread* self = Thread::Current();
1378  SirtRef<mirror::ObjectArray<mirror::ArtMethod> > imtable(self, cl->AllocArtMethodArray(self, 64));
1379  mirror::ArtMethod* imt_conflict_method = Runtime::Current()->GetImtConflictMethod();
1380  for (size_t i = 0; i < static_cast<size_t>(imtable->GetLength()); i++) {
1381    imtable->Set<false>(i, imt_conflict_method);
1382  }
1383  return imtable.get();
1384}
1385
1386mirror::ArtMethod* Runtime::CreateImtConflictMethod() {
1387  Thread* self = Thread::Current();
1388  Runtime* runtime = Runtime::Current();
1389  ClassLinker* class_linker = runtime->GetClassLinker();
1390  SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self));
1391  method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
1392  // TODO: use a special method for imt conflict method saves.
1393  method->SetDexMethodIndex(DexFile::kDexNoIndex);
1394  // When compiling, the code pointer will get set later when the image is loaded.
1395  if (runtime->IsCompiler()) {
1396    method->SetEntryPointFromPortableCompiledCode(nullptr);
1397    method->SetEntryPointFromQuickCompiledCode(nullptr);
1398  } else {
1399    method->SetEntryPointFromPortableCompiledCode(GetPortableImtConflictTrampoline(class_linker));
1400    method->SetEntryPointFromQuickCompiledCode(GetQuickImtConflictTrampoline(class_linker));
1401  }
1402  return method.get();
1403}
1404
1405mirror::ArtMethod* Runtime::CreateResolutionMethod() {
1406  Thread* self = Thread::Current();
1407  Runtime* runtime = Runtime::Current();
1408  ClassLinker* class_linker = runtime->GetClassLinker();
1409  SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self));
1410  method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
1411  // TODO: use a special method for resolution method saves
1412  method->SetDexMethodIndex(DexFile::kDexNoIndex);
1413  // When compiling, the code pointer will get set later when the image is loaded.
1414  if (runtime->IsCompiler()) {
1415    method->SetEntryPointFromPortableCompiledCode(nullptr);
1416    method->SetEntryPointFromQuickCompiledCode(nullptr);
1417  } else {
1418    method->SetEntryPointFromPortableCompiledCode(GetPortableResolutionTrampoline(class_linker));
1419    method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionTrampoline(class_linker));
1420  }
1421  return method.get();
1422}
1423
1424mirror::ArtMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set,
1425                                                   CalleeSaveType type) {
1426  Thread* self = Thread::Current();
1427  Runtime* runtime = Runtime::Current();
1428  ClassLinker* class_linker = runtime->GetClassLinker();
1429  SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self));
1430  method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
1431  // TODO: use a special method for callee saves
1432  method->SetDexMethodIndex(DexFile::kDexNoIndex);
1433  method->SetEntryPointFromPortableCompiledCode(nullptr);
1434  method->SetEntryPointFromQuickCompiledCode(nullptr);
1435  if ((instruction_set == kThumb2) || (instruction_set == kArm)) {
1436    uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6)  | (1 << art::arm::R7) |
1437                          (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11);
1438    uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3);
1439    uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9);
1440    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) |
1441                           (type == kSaveAll ? all_spills : 0) | (1 << art::arm::LR);
1442    uint32_t fp_all_spills = (1 << art::arm::S0)  | (1 << art::arm::S1)  | (1 << art::arm::S2) |
1443                             (1 << art::arm::S3)  | (1 << art::arm::S4)  | (1 << art::arm::S5) |
1444                             (1 << art::arm::S6)  | (1 << art::arm::S7)  | (1 << art::arm::S8) |
1445                             (1 << art::arm::S9)  | (1 << art::arm::S10) | (1 << art::arm::S11) |
1446                             (1 << art::arm::S12) | (1 << art::arm::S13) | (1 << art::arm::S14) |
1447                             (1 << art::arm::S15) | (1 << art::arm::S16) | (1 << art::arm::S17) |
1448                             (1 << art::arm::S18) | (1 << art::arm::S19) | (1 << art::arm::S20) |
1449                             (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) |
1450                             (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) |
1451                             (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) |
1452                             (1 << art::arm::S30) | (1 << art::arm::S31);
1453    uint32_t fp_spills = type == kSaveAll ? fp_all_spills : 0;
1454    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
1455                                 __builtin_popcount(fp_spills) /* fprs */ +
1456                                 1 /* Method* */) * kPointerSize, kStackAlignment);
1457    method->SetFrameSizeInBytes(frame_size);
1458    method->SetCoreSpillMask(core_spills);
1459    method->SetFpSpillMask(fp_spills);
1460  } else if (instruction_set == kMips) {
1461    uint32_t ref_spills = (1 << art::mips::S2) | (1 << art::mips::S3) | (1 << art::mips::S4) |
1462                          (1 << art::mips::S5) | (1 << art::mips::S6) | (1 << art::mips::S7) |
1463                          (1 << art::mips::GP) | (1 << art::mips::FP);
1464    uint32_t arg_spills = (1 << art::mips::A1) | (1 << art::mips::A2) | (1 << art::mips::A3);
1465    uint32_t all_spills = (1 << art::mips::S0) | (1 << art::mips::S1);
1466    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) |
1467                           (type == kSaveAll ? all_spills : 0) | (1 << art::mips::RA);
1468    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
1469                                (type == kRefsAndArgs ? 0 : 3) + 1 /* Method* */) *
1470                                kPointerSize, kStackAlignment);
1471    method->SetFrameSizeInBytes(frame_size);
1472    method->SetCoreSpillMask(core_spills);
1473    method->SetFpSpillMask(0);
1474  } else if (instruction_set == kX86) {
1475    uint32_t ref_spills = (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI);
1476    uint32_t arg_spills = (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX);
1477    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) |
1478                         (1 << art::x86::kNumberOfCpuRegisters);  // fake return address callee save
1479    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
1480                                 1 /* Method* */) * kPointerSize, kStackAlignment);
1481    method->SetFrameSizeInBytes(frame_size);
1482    method->SetCoreSpillMask(core_spills);
1483    method->SetFpSpillMask(0);
1484  } else if (instruction_set == kX86_64) {
1485    uint32_t ref_spills =
1486        (1 << art::x86_64::RBX) | (1 << art::x86_64::RBP) | (1 << art::x86_64::R12) |
1487        (1 << art::x86_64::R13) | (1 << art::x86_64::R14) | (1 << art::x86_64::R15);
1488    uint32_t arg_spills =
1489        (1 << art::x86_64::RSI) | (1 << art::x86_64::RDX) | (1 << art::x86_64::RCX) |
1490        (1 << art::x86_64::R8) | (1 << art::x86_64::R9);
1491    uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) |
1492                         (1 << art::x86::kNumberOfCpuRegisters);  // fake return address callee save
1493    size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ +
1494                                 1 /* Method* */) * kPointerSize, kStackAlignment);
1495    method->SetFrameSizeInBytes(frame_size);
1496    method->SetCoreSpillMask(core_spills);
1497    method->SetFpSpillMask(0);
1498  } else {
1499    UNIMPLEMENTED(FATAL) << instruction_set;
1500  }
1501  return method.get();
1502}
1503
1504void Runtime::DisallowNewSystemWeaks() {
1505  monitor_list_->DisallowNewMonitors();
1506  intern_table_->DisallowNewInterns();
1507  java_vm_->DisallowNewWeakGlobals();
1508  Dbg::DisallowNewObjectRegistryObjects();
1509}
1510
1511void Runtime::AllowNewSystemWeaks() {
1512  monitor_list_->AllowNewMonitors();
1513  intern_table_->AllowNewInterns();
1514  java_vm_->AllowNewWeakGlobals();
1515  Dbg::AllowNewObjectRegistryObjects();
1516}
1517
1518void Runtime::SetCalleeSaveMethod(mirror::ArtMethod* method, CalleeSaveType type) {
1519  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
1520  callee_save_methods_[type] = method;
1521}
1522
1523const std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(jobject class_loader) {
1524  if (class_loader == NULL) {
1525    return GetClassLinker()->GetBootClassPath();
1526  }
1527  CHECK(UseCompileTimeClassPath());
1528  CompileTimeClassPaths::const_iterator it = compile_time_class_paths_.find(class_loader);
1529  CHECK(it != compile_time_class_paths_.end());
1530  return it->second;
1531}
1532
1533void Runtime::SetCompileTimeClassPath(jobject class_loader, std::vector<const DexFile*>& class_path) {
1534  CHECK(!IsStarted());
1535  use_compile_time_class_path_ = true;
1536  compile_time_class_paths_.Put(class_loader, class_path);
1537}
1538
1539void Runtime::AddMethodVerifier(verifier::MethodVerifier* verifier) {
1540  DCHECK(verifier != nullptr);
1541  MutexLock mu(Thread::Current(), method_verifiers_lock_);
1542  method_verifiers_.insert(verifier);
1543}
1544
1545void Runtime::RemoveMethodVerifier(verifier::MethodVerifier* verifier) {
1546  DCHECK(verifier != nullptr);
1547  MutexLock mu(Thread::Current(), method_verifiers_lock_);
1548  auto it = method_verifiers_.find(verifier);
1549  CHECK(it != method_verifiers_.end());
1550  method_verifiers_.erase(it);
1551}
1552
1553void Runtime::StartProfiler(const char *appDir, bool startImmediately) {
1554  BackgroundMethodSamplingProfiler::Start(profile_period_s_, profile_duration_s_, appDir, profile_interval_us_,
1555      profile_backoff_coefficient_, startImmediately);
1556}
1557
1558// Transaction support.
1559// TODO move them to header file for inlining.
1560bool Runtime::IsActiveTransaction() const {
1561  return preinitialization_transaction != nullptr;
1562}
1563
1564void Runtime::EnterTransactionMode(Transaction* transaction) {
1565  DCHECK(IsCompiler());
1566  DCHECK(transaction != nullptr);
1567  DCHECK(!IsActiveTransaction());
1568  preinitialization_transaction = transaction;
1569}
1570
1571void Runtime::ExitTransactionMode() {
1572  DCHECK(IsCompiler());
1573  DCHECK(IsActiveTransaction());
1574  preinitialization_transaction = nullptr;
1575}
1576
1577void Runtime::RecordWriteField32(mirror::Object* obj, MemberOffset field_offset,
1578                                 uint32_t value, bool is_volatile) const {
1579  DCHECK(IsCompiler());
1580  DCHECK(IsActiveTransaction());
1581  preinitialization_transaction->RecordWriteField32(obj, field_offset, value, is_volatile);
1582}
1583
1584void Runtime::RecordWriteField64(mirror::Object* obj, MemberOffset field_offset,
1585                                 uint64_t value, bool is_volatile) const {
1586  DCHECK(IsCompiler());
1587  DCHECK(IsActiveTransaction());
1588  preinitialization_transaction->RecordWriteField64(obj, field_offset, value, is_volatile);
1589}
1590
1591void Runtime::RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
1592                                        mirror::Object* value, bool is_volatile) const {
1593  DCHECK(IsCompiler());
1594  DCHECK(IsActiveTransaction());
1595  preinitialization_transaction->RecordWriteFieldReference(obj, field_offset, value, is_volatile);
1596}
1597
1598void Runtime::RecordWriteArray(mirror::Array* array, size_t index, uint64_t value) const {
1599  DCHECK(IsCompiler());
1600  DCHECK(IsActiveTransaction());
1601  preinitialization_transaction->RecordWriteArray(array, index, value);
1602}
1603
1604void Runtime::RecordStrongStringInsertion(mirror::String* s, uint32_t hash_code) const {
1605  DCHECK(IsCompiler());
1606  DCHECK(IsActiveTransaction());
1607  preinitialization_transaction->RecordStrongStringInsertion(s, hash_code);
1608}
1609
1610void Runtime::RecordWeakStringInsertion(mirror::String* s, uint32_t hash_code) const {
1611  DCHECK(IsCompiler());
1612  DCHECK(IsActiveTransaction());
1613  preinitialization_transaction->RecordWeakStringInsertion(s, hash_code);
1614}
1615
1616void Runtime::RecordStrongStringRemoval(mirror::String* s, uint32_t hash_code) const {
1617  DCHECK(IsCompiler());
1618  DCHECK(IsActiveTransaction());
1619  preinitialization_transaction->RecordStrongStringRemoval(s, hash_code);
1620}
1621
1622void Runtime::RecordWeakStringRemoval(mirror::String* s, uint32_t hash_code) const {
1623  DCHECK(IsCompiler());
1624  DCHECK(IsActiveTransaction());
1625  preinitialization_transaction->RecordWeakStringRemoval(s, hash_code);
1626}
1627}  // namespace art
1628