// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/jit/compiler.h"

#include "vm/compiler/assembler/assembler.h"

#include "vm/ast_printer.h"
#include "vm/code_patcher.h"
#include "vm/compiler/aot/precompiler.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/compiler/backend/block_scheduler.h"
#include "vm/compiler/backend/branch_optimizer.h"
#include "vm/compiler/backend/constant_propagator.h"
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/inliner.h"
#include "vm/compiler/backend/linearscan.h"
#include "vm/compiler/backend/range_analysis.h"
#include "vm/compiler/backend/redundancy_elimination.h"
#include "vm/compiler/backend/type_propagator.h"
#include "vm/compiler/cha.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/compiler/compiler_state.h"
#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/frontend/flow_graph_builder.h"
#include "vm/compiler/frontend/kernel_to_il.h"
#include "vm/compiler/jit/jit_call_specializer.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/deopt_instructions.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/kernel.h"
#include "vm/kernel_loader.h"  // For kernel::ParseStaticFieldInitializer.
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/os.h"
#include "vm/parser.h"
#include "vm/regexp_assembler.h"
#include "vm/regexp_parser.h"
#include "vm/runtime_entry.h"
#include "vm/symbols.h"
#include "vm/tags.h"
#include "vm/thread_registry.h"
#include "vm/timeline.h"
#include "vm/timer.h"

namespace dart {

DEFINE_FLAG(
    int,
    max_deoptimization_counter_threshold,
    16,
    "How many times we allow deoptimization before we disallow optimization.");
DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function");
DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
DEFINE_FLAG(bool,
            print_flow_graph_optimized,
            false,
            "Print the IR flow graph when optimizing.");
DEFINE_FLAG(bool,
            print_ic_data_map,
            false,
            "Print the deopt-id to ICData map in optimizing compiler.");
DEFINE_FLAG(bool, print_code_source_map, false, "Print code source map.");
DEFINE_FLAG(bool,
            stress_test_background_compilation,
            false,
            "Keep background compiler running all the time");
DEFINE_FLAG(bool,
            stop_on_excessive_deoptimization,
            false,
            "Debugging: stops program if deoptimizing same function too often");
DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
DEFINE_FLAG(bool,
            trace_failed_optimization_attempts,
            false,
            "Traces all failed optimization attempts");
DEFINE_FLAG(bool,
            trace_optimizing_compiler,
            false,
            "Trace only optimizing compiler operations.");
DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
DEFINE_FLAG(bool,
            verify_compiler,
            false,
            "Enable compiler verification assertions");

DECLARE_FLAG(bool, enable_interpreter);
DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
DECLARE_FLAG(bool, trace_failed_optimization_attempts);
DECLARE_FLAG(bool, unbox_numeric_fields);

static void PrecompilationModeHandler(bool value) {
  if (value) {
#if defined(TARGET_ARCH_IA32)
    FATAL("Precompilation not supported on IA32");
#endif

    FLAG_background_compilation = false;
    FLAG_collect_code = false;
    FLAG_enable_mirrors = false;
    FLAG_fields_may_be_reset = true;
    FLAG_interpret_irregexp = true;
    FLAG_lazy_dispatchers = false;
    FLAG_link_natives_lazily = true;
    FLAG_optimization_counter_threshold = -1;
    FLAG_polymorphic_with_deopt = false;
    FLAG_precompiled_mode = true;
    FLAG_reorder_basic_blocks = false;
    FLAG_use_field_guards = false;
    FLAG_use_cha_deopt = false;

#if !defined(DART_PRECOMPILED_RUNTIME)
    // Not present with DART_PRECOMPILED_RUNTIME
    FLAG_unbox_numeric_fields = false;
#endif

#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    // Set flags affecting runtime accordingly for dart_bootstrap.
    // These flags are constants with PRODUCT and DART_PRECOMPILED_RUNTIME.
    FLAG_deoptimize_alot = false;  // Used in some tests.
    FLAG_deoptimize_every = 0;     // Used in some tests.
    FLAG_load_deferred_eagerly = true;
    FLAG_print_stop_message = false;
    FLAG_use_osr = false;
#endif
  }
}

DEFINE_FLAG_HANDLER(PrecompilationModeHandler,
                    precompilation,
                    "Precompilation mode");

#ifndef DART_PRECOMPILED_RUNTIME

bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
  const Function& function = parsed_function->function();
  return (function.kernel_offset() > 0) || function.HasBytecode() ||
         (function.kind() == RawFunction::kNoSuchMethodDispatcher) ||
         (function.kind() == RawFunction::kInvokeFieldDispatcher);
}

void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) {
  if (!UseKernelFrontEndFor(parsed_function)) {
    Parser::ParseFunction(parsed_function);
    parsed_function->AllocateVariables();
  }
}

FlowGraph* DartCompilationPipeline::BuildFlowGraph(
    Zone* zone,
    ParsedFunction* parsed_function,
    ZoneGrowableArray<const ICData*>* ic_data_array,
    intptr_t osr_id,
    bool optimized) {
  if (UseKernelFrontEndFor(parsed_function)) {
    kernel::FlowGraphBuilder builder(parsed_function, ic_data_array,
                                     /* not building var desc */ NULL,
                                     /* not inlining */ NULL, optimized,
                                     osr_id);
    FlowGraph* graph = builder.BuildGraph();
    ASSERT(graph != NULL);
    return graph;
  }
  FlowGraphBuilder builder(*parsed_function, *ic_data_array,
                           /* not building var desc */ NULL,
                           /* not inlining */ NULL, osr_id);

  return builder.BuildGraph();
}

void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {}

void IrregexpCompilationPipeline::ParseFunction(
    ParsedFunction* parsed_function) {
  VMTagScope tagScope(parsed_function->thread(),
                      VMTag::kCompileParseRegExpTagId);
  Zone* zone = parsed_function->zone();
  RegExp& regexp = RegExp::Handle(parsed_function->function().regexp());

  const String& pattern = String::Handle(regexp.pattern());
  const bool multiline = regexp.is_multi_line();

  RegExpCompileData* compile_data = new (zone) RegExpCompileData();
  if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) {
    // Parsing failures are handled in the RegExp factory constructor.
    UNREACHABLE();
  }

  regexp.set_num_bracket_expressions(compile_data->capture_count);
  if (compile_data->simple) {
    regexp.set_is_simple();
  } else {
    regexp.set_is_complex();
  }

  parsed_function->SetRegExpCompileData(compile_data);

  // Variables are allocated after compilation.
}

FlowGraph* IrregexpCompilationPipeline::BuildFlowGraph(
    Zone* zone,
    ParsedFunction* parsed_function,
    ZoneGrowableArray<const ICData*>* ic_data_array,
    intptr_t osr_id,
    bool optimized) {
  // Compile to the dart IR.
  RegExpEngine::CompilationResult result =
      RegExpEngine::CompileIR(parsed_function->regexp_compile_data(),
                              parsed_function, *ic_data_array, osr_id);
  backtrack_goto_ = result.backtrack_goto;

  // Allocate variables now that we know the number of locals.
  parsed_function->AllocateIrregexpVariables(result.num_stack_locals);

  // When compiling for OSR, use a depth first search to find the OSR
  // entry and make graph entry jump to it instead of normal entry.
  // Catch entries are always considered reachable, even if they
  // become unreachable after OSR.
  if (osr_id != Compiler::kNoOSRDeoptId) {
    result.graph_entry->RelinkToOsrEntry(zone, result.num_blocks);
  }
  PrologueInfo prologue_info(-1, -1);
  return new (zone) FlowGraph(*parsed_function, result.graph_entry,
                              result.num_blocks, prologue_info);
}

void IrregexpCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {
  backtrack_goto_->ComputeOffsetTable();
}

CompilationPipeline* CompilationPipeline::New(Zone* zone,
                                              const Function& function) {
  if (function.IsIrregexpFunction()) {
    return new (zone) IrregexpCompilationPipeline();
  } else {
    return new (zone) DartCompilationPipeline();
  }
}

// Compile a function. Should call only if the function has not been compiled.
//   Arg0: function object.
DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
  const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
  Object& result = Object::Handle(zone);

  if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) {
    if (!function.HasBytecode()) {
      result = kernel::BytecodeReader::ReadFunctionBytecode(thread, function);
      if (!result.IsNull()) {
        Exceptions::PropagateError(Error::Cast(result));
      }
    }
    if (function.HasBytecode()) {
      // If interpreter is enabled and there is bytecode, LazyCompile stub
      // (which calls CompileFunction) should proceed to InterpretCall in order
      // to enter interpreter. In such case, compilation is postponed and
      // triggered by interpreter later via OptimizeInvokedFunction.
      return;
    }
    // No bytecode, fall back to compilation.
  } else {
    ASSERT(!function.HasCode());
  }

  result = Compiler::CompileFunction(thread, function);
  if (result.IsError()) {
    if (result.IsLanguageError()) {
      Exceptions::ThrowCompileTimeError(LanguageError::Cast(result));
      UNREACHABLE();
    }
    Exceptions::PropagateError(Error::Cast(result));
  }
}

bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
#if !defined(PRODUCT)
  Isolate* isolate = thread->isolate();
  if (isolate->debugger()->IsStepping() ||
      isolate->debugger()->HasBreakpoint(function, thread->zone())) {
    // We cannot set breakpoints and single step in optimized code,
    // so do not optimize the function. Bump usage counter down to avoid
    // repeatedly entering the runtime for an optimization attempt.
    function.SetUsageCounter(0);
    return false;
  }
#endif
  if (function.deoptimization_counter() >=
      FLAG_max_deoptimization_counter_threshold) {
    if (FLAG_trace_failed_optimization_attempts ||
        FLAG_stop_on_excessive_deoptimization) {
      THR_Print("Too many deoptimizations: %s\n",
                function.ToFullyQualifiedCString());
      if (FLAG_stop_on_excessive_deoptimization) {
        FATAL("Stop on excessive deoptimization");
      }
    }
    // The function will not be optimized any longer. This situation can occur
    // mostly with small optimization counter thresholds.
    function.SetIsOptimizable(false);
    function.SetUsageCounter(INT_MIN);
    return false;
  }
  if (FLAG_optimization_filter != NULL) {
    // FLAG_optimization_filter is a comma-separated list of strings that are
    // matched against the fully-qualified function name.
    char* save_ptr;  // Needed for strtok_r.
    const char* function_name = function.ToFullyQualifiedCString();
    intptr_t len = strlen(FLAG_optimization_filter) + 1;  // Length with \0.
    char* filter = new char[len];
    strncpy(filter, FLAG_optimization_filter, len);  // strtok modifies arg 1.
    char* token = strtok_r(filter, ",", &save_ptr);
    bool found = false;
    while (token != NULL) {
      if (strstr(function_name, token) != NULL) {
        found = true;
        break;
      }
      token = strtok_r(NULL, ",", &save_ptr);
    }
    delete[] filter;
    if (!found) {
      function.SetUsageCounter(INT_MIN);
      return false;
    }
  }
  if (!function.IsOptimizable()) {
    // Huge methods (code size above --huge_method_cutoff_in_code_size) become
    // non-optimizable only after the code has been generated.
    if (FLAG_trace_failed_optimization_attempts) {
      THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString());
    }
    function.SetUsageCounter(INT_MIN);
    return false;
  }
  return true;
}

bool Compiler::IsBackgroundCompilation() {
  // For now: compilation in non mutator thread is the background compoilation.
  return !Thread::Current()->IsMutatorThread();
}

RawError* Compiler::Compile(const Library& library, const Script& script) {
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Thread* const thread = Thread::Current();
    StackZone zone(thread);
    if (FLAG_trace_compiler) {
      const String& script_url = String::Handle(script.url());
      // TODO(iposva): Extract script kind.
      THR_Print("Compiling %s '%s'\n", "", script_url.ToCString());
    }
    const String& library_key = String::Handle(library.private_key());
    script.Tokenize(library_key);
    Parser::ParseCompilationUnit(library, script);
    return Error::null();
  } else {
    Thread* const thread = Thread::Current();
    StackZone zone(thread);
    Error& error = Error::Handle();
    error = thread->sticky_error();
    thread->clear_sticky_error();
    return error.raw();
  }
  UNREACHABLE();
  return Error::null();
}

static void AddRelatedClassesToList(
    const Class& cls,
    GrowableHandlePtrArray<const Class>* parse_list,
    GrowableHandlePtrArray<const Class>* patch_list) {
  Zone* zone = Thread::Current()->zone();
  Class& parse_class = Class::Handle(zone);
  AbstractType& interface_type = Type::Handle(zone);
  Array& interfaces = Array::Handle(zone);

  // Add all the interfaces implemented by the class that have not been
  // already parsed to the parse list. Mark the interface as parsed so that
  // we don't recursively add it back into the list.
  interfaces ^= cls.interfaces();
  for (intptr_t i = 0; i < interfaces.Length(); i++) {
    interface_type ^= interfaces.At(i);
    parse_class ^= interface_type.type_class();
    if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
      parse_list->Add(parse_class);
      parse_class.set_is_marked_for_parsing();
    }
  }

  // Walk up the super_class chain and add these classes to the list if they
  // have not been already parsed to the parse list. Mark the class as parsed
  // so that we don't recursively add it back into the list.
  parse_class ^= cls.SuperClass();
  while (!parse_class.IsNull()) {
    if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
      parse_list->Add(parse_class);
      parse_class.set_is_marked_for_parsing();
    }
    parse_class ^= parse_class.SuperClass();
  }

  // Add patch classes if they exist to the parse list if they have not already
  // been parsed and patched. Mark the class as parsed so that we don't
  // recursively add it back into the list.
  parse_class ^= cls.GetPatchClass();
  if (!parse_class.IsNull()) {
    if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
      patch_list->Add(parse_class);
      parse_class.set_is_marked_for_parsing();
    }
  }
}

RawError* Compiler::CompileClass(const Class& cls) {
  ASSERT(Thread::Current()->IsMutatorThread());
  // If class is a top level class it is already parsed.
  if (cls.IsTopLevel()) {
    return Error::null();
  }
  // If the class is already marked for parsing return immediately.
  if (cls.is_marked_for_parsing()) {
    return Error::null();
  }
  // If the class is a typedef class there is no need to try and
  // compile it. Just finalize it directly.
  if (cls.IsTypedefClass()) {
#if defined(DEBUG)
    const Class& closure_cls =
        Class::Handle(Isolate::Current()->object_store()->closure_class());
    ASSERT(closure_cls.is_finalized());
#endif
    LongJumpScope jump;
    if (setjmp(*jump.Set()) == 0) {
      ClassFinalizer::FinalizeClass(cls);
      return Error::null();
    } else {
      Thread* thread = Thread::Current();
      Error& error = Error::Handle(thread->zone());
      error = thread->sticky_error();
      thread->clear_sticky_error();
      return error.raw();
    }
  }

  Thread* const thread = Thread::Current();
  StackZone zone(thread);
#if !defined(PRODUCT)
  VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
  TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
                            "CompileClass");
  if (tds.enabled()) {
    tds.SetNumArguments(1);
    tds.CopyArgument(0, "class", cls.ToCString());
  }
#endif  // !defined(PRODUCT)

  // We remember all the classes that are being compiled in these lists. This
  // also allows us to reset the marked_for_parsing state in case we see an
  // error.
  GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
  GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4);

  // Parse the class and all the interfaces it implements and super classes.
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    if (FLAG_trace_compiler) {
      THR_Print("Compiling Class '%s'\n", cls.ToCString());
    }

    // Add the primary class which needs to be parsed to the parse list.
    // Mark the class as parsed so that we don't recursively add the same
    // class back into the list.
    parse_list.Add(cls);
    cls.set_is_marked_for_parsing();

    // Add all super classes, interface classes and patch class if one
    // exists to the corresponding lists.
    // NOTE: The parse_list array keeps growing as more classes are added
    // to it by AddRelatedClassesToList. It is not OK to hoist
    // parse_list.Length() into a local variable and iterate using the local
    // variable.
    for (intptr_t i = 0; i < parse_list.length(); i++) {
      AddRelatedClassesToList(parse_list.At(i), &parse_list, &patch_list);
    }

    // Classes loaded from a kernel should not be parsed.
    if (cls.kernel_offset() <= 0) {
      // Parse all the classes that have been added above.
      for (intptr_t i = (parse_list.length() - 1); i >= 0; i--) {
        const Class& parse_class = parse_list.At(i);
        ASSERT(!parse_class.IsNull());
        Parser::ParseClass(parse_class);
      }

      // Parse all the patch classes that have been added above.
      for (intptr_t i = 0; i < patch_list.length(); i++) {
        const Class& parse_class = patch_list.At(i);
        ASSERT(!parse_class.IsNull());
        Parser::ParseClass(parse_class);
      }
    }

    // Finalize these classes.
    for (intptr_t i = (parse_list.length() - 1); i >= 0; i--) {
      const Class& parse_class = parse_list.At(i);
      ASSERT(!parse_class.IsNull());
      ClassFinalizer::FinalizeClass(parse_class);
      parse_class.reset_is_marked_for_parsing();
    }
    for (intptr_t i = (patch_list.length() - 1); i >= 0; i--) {
      const Class& parse_class = patch_list.At(i);
      ASSERT(!parse_class.IsNull());
      ClassFinalizer::FinalizeClass(parse_class);
      parse_class.reset_is_marked_for_parsing();
    }

    return Error::null();
  } else {
    // Reset the marked for parsing flags.
    for (intptr_t i = 0; i < parse_list.length(); i++) {
      const Class& parse_class = parse_list.At(i);
      if (parse_class.is_marked_for_parsing()) {
        parse_class.reset_is_marked_for_parsing();
      }
    }
    for (intptr_t i = 0; i < patch_list.length(); i++) {
      const Class& parse_class = patch_list.At(i);
      if (parse_class.is_marked_for_parsing()) {
        parse_class.reset_is_marked_for_parsing();
      }
    }
    Thread* thread = Thread::Current();
    Error& error = Error::Handle(thread->zone());
    error = thread->sticky_error();
    thread->clear_sticky_error();
    return error.raw();
  }
  UNREACHABLE();
  return Error::null();
}

class CompileParsedFunctionHelper : public ValueObject {
 public:
  CompileParsedFunctionHelper(ParsedFunction* parsed_function,
                              bool optimized,
                              intptr_t osr_id)
      : parsed_function_(parsed_function),
        optimized_(optimized),
        osr_id_(osr_id),
        thread_(Thread::Current()),
        loading_invalidation_gen_at_start_(
            isolate()->loading_invalidation_gen()) {}

  RawCode* Compile(CompilationPipeline* pipeline);

 private:
  ParsedFunction* parsed_function() const { return parsed_function_; }
  bool optimized() const { return optimized_; }
  intptr_t osr_id() const { return osr_id_; }
  Thread* thread() const { return thread_; }
  Isolate* isolate() const { return thread_->isolate(); }
  intptr_t loading_invalidation_gen_at_start() const {
    return loading_invalidation_gen_at_start_;
  }
  RawCode* FinalizeCompilation(Assembler* assembler,
                               FlowGraphCompiler* graph_compiler,
                               FlowGraph* flow_graph);
  void CheckIfBackgroundCompilerIsBeingStopped();

  ParsedFunction* parsed_function_;
  const bool optimized_;
  const intptr_t osr_id_;
  Thread* const thread_;
  const intptr_t loading_invalidation_gen_at_start_;

  DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
};

RawCode* CompileParsedFunctionHelper::FinalizeCompilation(
    Assembler* assembler,
    FlowGraphCompiler* graph_compiler,
    FlowGraph* flow_graph) {
  ASSERT(!FLAG_precompiled_mode);
  const Function& function = parsed_function()->function();
  Zone* const zone = thread()->zone();

  CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer);
  // CreateDeoptInfo uses the object pool and needs to be done before
  // FinalizeCode.
  const Array& deopt_info_array =
      Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler));
  INC_STAT(thread(), total_code_size,
           deopt_info_array.Length() * sizeof(uword));
  // Allocates instruction object. Since this occurs only at safepoint,
  // there can be no concurrent access to the instruction page.
  Code& code = Code::Handle(Code::FinalizeCode(
      function, graph_compiler, assembler, optimized(), /*stats=*/nullptr));
  code.set_is_optimized(optimized());
  code.set_owner(function);
#if !defined(PRODUCT)
  ZoneGrowableArray<TokenPosition>* await_token_positions =
      flow_graph->await_token_positions();
  if (await_token_positions != NULL) {
    Smi& token_pos_value = Smi::Handle(zone);
    if (await_token_positions->length() > 0) {
      const Array& await_to_token_map = Array::Handle(
          zone, Array::New(await_token_positions->length(), Heap::kOld));
      ASSERT(!await_to_token_map.IsNull());
      for (intptr_t i = 0; i < await_token_positions->length(); i++) {
        TokenPosition token_pos = await_token_positions->At(i).FromSynthetic();
        if (!token_pos.IsReal()) {
          // Some async machinary uses sentinel values. Map them to
          // no source position.
          token_pos_value = Smi::New(TokenPosition::kNoSourcePos);
        } else {
          token_pos_value = Smi::New(token_pos.value());
        }
        await_to_token_map.SetAt(i, token_pos_value);
      }
      code.set_await_token_positions(await_to_token_map);
    }
  }
#endif  // !defined(PRODUCT)

  if (!function.IsOptimizable()) {
    // A function with huge unoptimized code can become non-optimizable
    // after generating unoptimized code.
    function.SetUsageCounter(INT_MIN);
  }

  graph_compiler->FinalizePcDescriptors(code);
  code.set_deopt_info_array(deopt_info_array);

  graph_compiler->FinalizeStackMaps(code);
  graph_compiler->FinalizeVarDescriptors(code);
  graph_compiler->FinalizeExceptionHandlers(code);
  graph_compiler->FinalizeCatchEntryMovesMap(code);
  graph_compiler->FinalizeStaticCallTargetsTable(code);
  graph_compiler->FinalizeCodeSourceMap(code);

  if (optimized()) {
    // Installs code while at safepoint.
    if (thread()->IsMutatorThread()) {
      const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
      if (!is_osr) {
        function.InstallOptimizedCode(code);
      }
      ASSERT(code.owner() == function.raw());
    } else {
      // Background compilation.
      // Before installing code check generation counts if the code may
      // have become invalid.
      const bool trace_compiler =
          FLAG_trace_compiler || FLAG_trace_optimizing_compiler;
      bool code_is_valid = true;
      if (!flow_graph->parsed_function().guarded_fields()->is_empty()) {
        const ZoneGrowableArray<const Field*>& guarded_fields =
            *flow_graph->parsed_function().guarded_fields();
        Field& original = Field::Handle();
        for (intptr_t i = 0; i < guarded_fields.length(); i++) {
          const Field& field = *guarded_fields[i];
          ASSERT(!field.IsOriginal());
          original = field.Original();
          if (!field.IsConsistentWith(original)) {
            code_is_valid = false;
            if (trace_compiler) {
              THR_Print("--> FAIL: Field %s guarded state changed.",
                        field.ToCString());
            }
            break;
          }
        }
      }
      if (loading_invalidation_gen_at_start() !=
          isolate()->loading_invalidation_gen()) {
        code_is_valid = false;
        if (trace_compiler) {
          THR_Print("--> FAIL: Loading invalidation.");
        }
      }
      if (!thread()
               ->compiler_state()
               .cha()
               .IsConsistentWithCurrentHierarchy()) {
        code_is_valid = false;
        if (trace_compiler) {
          THR_Print("--> FAIL: Class hierarchy has new subclasses.");
        }
      }

      // Setting breakpoints at runtime could make a function non-optimizable.
      if (code_is_valid && Compiler::CanOptimizeFunction(thread(), function)) {
        const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
        ASSERT(!is_osr);  // OSR is not compiled in background.
        function.InstallOptimizedCode(code);
      } else {
        code = Code::null();
      }
      if (function.usage_counter() < 0) {
        // Reset to 0 so that it can be recompiled if needed.
        if (code_is_valid) {
          function.SetUsageCounter(0);
        } else {
          // Trigger another optimization pass soon.
          function.SetUsageCounter(FLAG_optimization_counter_threshold - 100);
        }
      }
    }

    if (!code.IsNull()) {
      // The generated code was compiled under certain assumptions about
      // class hierarchy and field types. Register these dependencies
      // to ensure that the code will be deoptimized if they are violated.
      thread()->compiler_state().cha().RegisterDependencies(code);

      const ZoneGrowableArray<const Field*>& guarded_fields =
          *flow_graph->parsed_function().guarded_fields();
      Field& field = Field::Handle();
      for (intptr_t i = 0; i < guarded_fields.length(); i++) {
        field = guarded_fields[i]->Original();
        field.RegisterDependentCode(code);
      }
    }
  } else {  // not optimized.
    if (function.ic_data_array() == Array::null()) {
      function.SaveICDataMap(
          graph_compiler->deopt_id_to_ic_data(),
          Array::Handle(zone, graph_compiler->edge_counters_array()));
    }
    function.set_unoptimized_code(code);
    function.AttachCode(code);
  }
  if (parsed_function()->HasDeferredPrefixes()) {
    ASSERT(!FLAG_load_deferred_eagerly);
    ZoneGrowableArray<const LibraryPrefix*>* prefixes =
        parsed_function()->deferred_prefixes();
    for (intptr_t i = 0; i < prefixes->length(); i++) {
      (*prefixes)[i]->RegisterDependentCode(code);
    }
  }
  return code.raw();
}

void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() {
  ASSERT(Compiler::IsBackgroundCompilation());
  if (!isolate()->background_compiler()->is_running()) {
    // The background compiler is being stopped.
    Compiler::AbortBackgroundCompilation(
        DeoptId::kNone, "Background compilation is being stopped");
  }
}

// Return null if bailed out.
// If optimized_result_code is not NULL then it is caller's responsibility
// to install code.
RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
  ASSERT(!FLAG_precompiled_mode);
  const Function& function = parsed_function()->function();
  if (optimized() && !function.IsOptimizable()) {
    return Code::null();
  }
  Zone* const zone = thread()->zone();
  NOT_IN_PRODUCT(TimelineStream* compiler_timeline =
                     Timeline::GetCompilerStream());
  CSTAT_TIMER_SCOPE(thread(), codegen_timer);
  HANDLESCOPE(thread());

  // We may reattempt compilation if the function needs to be assembled using
  // far branches on ARM. In the else branch of the setjmp call, done is set to
  // false, and use_far_branches is set to true if there is a longjmp from the
  // ARM assembler. In all other paths through this while loop, done is set to
  // true. use_far_branches is always false on ia32 and x64.
  volatile bool done = false;
  // volatile because the variable may be clobbered by a longjmp.
  volatile bool use_far_branches = false;

  // In the JIT case we allow speculative inlining and have no need for a
  // blacklist, since we don't restart optimization.
  SpeculativeInliningPolicy speculative_policy(/* enable_blacklist= */ false);

  Code* volatile result = &Code::ZoneHandle(zone);
  while (!done) {
    *result = Code::null();
    LongJumpScope jump;
    if (setjmp(*jump.Set()) == 0) {
      FlowGraph* flow_graph = nullptr;
      ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;

      CompilerState compiler_state(thread());

      // TimerScope needs an isolate to be properly terminated in case of a
      // LongJump.
      {
        CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer);

        if (optimized()) {
          // In background compilation the deoptimization counter may have
          // already reached the limit.
          ASSERT(Compiler::IsBackgroundCompilation() ||
                 (function.deoptimization_counter() <
                  FLAG_max_deoptimization_counter_threshold));
        }

        // Extract type feedback before the graph is built, as the graph
        // builder uses it to attach it to nodes.
        ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();

        // Clone ICData for background compilation so that it does not
        // change while compiling.
        const bool clone_ic_data = Compiler::IsBackgroundCompilation();
        function.RestoreICDataMap(ic_data_array, clone_ic_data);

        if (optimized()) {
          if (Compiler::IsBackgroundCompilation() &&
              (function.ic_data_array() == Array::null())) {
            Compiler::AbortBackgroundCompilation(
                DeoptId::kNone, "RestoreICDataMap: ICData array cleared.");
          }
        }

        if (FLAG_print_ic_data_map) {
          for (intptr_t i = 0; i < ic_data_array->length(); i++) {
            if ((*ic_data_array)[i] != NULL) {
              THR_Print("%" Pd " ", i);
              FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
            }
          }
        }

        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
                                                 "BuildFlowGraph"));
        flow_graph = pipeline->BuildFlowGraph(
            zone, parsed_function(), ic_data_array, osr_id(), optimized());
      }

      const bool print_flow_graph =
          (FLAG_print_flow_graph ||
           (optimized() && FLAG_print_flow_graph_optimized)) &&
          FlowGraphPrinter::ShouldPrint(function);

      if (print_flow_graph && !optimized()) {
        FlowGraphPrinter::PrintGraph("Unoptimized Compilation", flow_graph);
      }

      BlockScheduler block_scheduler(flow_graph);
      const bool reorder_blocks =
          FlowGraph::ShouldReorderBlocks(function, optimized());
      if (reorder_blocks) {
        NOT_IN_PRODUCT(TimelineDurationScope tds(
            thread(), compiler_timeline, "BlockScheduler::AssignEdgeWeights"));
        block_scheduler.AssignEdgeWeights();
      }

      CompilerPassState pass_state(thread(), flow_graph, &speculative_policy);
      NOT_IN_PRODUCT(pass_state.compiler_timeline = compiler_timeline);
      pass_state.block_scheduler = &block_scheduler;
      pass_state.reorder_blocks = reorder_blocks;

      if (optimized()) {
        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
                                                 "OptimizationPasses"));
        CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);

        pass_state.inline_id_to_function.Add(&function);
        // We do not add the token position now because we don't know the
        // position of the inlined call until later. A side effect of this
        // is that the length of |inline_id_to_function| is always larger
        // than the length of |inline_id_to_token_pos| by one.
        // Top scope function has no caller (-1). We do this because we expect
        // all token positions to be at an inlined call.
        pass_state.caller_inline_id.Add(-1);

        JitCallSpecializer call_specializer(flow_graph, &speculative_policy);
        pass_state.call_specializer = &call_specializer;

        CompilerPass::RunPipeline(CompilerPass::kJIT, &pass_state);
      }

      ASSERT(pass_state.inline_id_to_function.length() ==
             pass_state.caller_inline_id.length());
      ObjectPoolWrapper object_pool_wrapper;
      Assembler assembler(&object_pool_wrapper, use_far_branches);
      FlowGraphCompiler graph_compiler(
          &assembler, flow_graph, *parsed_function(), optimized(),
          &speculative_policy, pass_state.inline_id_to_function,
          pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
          ic_data_array);
      {
        CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
                                                 "CompileGraph"));
        graph_compiler.CompileGraph();
        pipeline->FinalizeCompilation(flow_graph);
      }
      {
        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
                                                 "FinalizeCompilation"));
        if (thread()->IsMutatorThread()) {
          *result =
              FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
        } else {
          // This part of compilation must be at a safepoint.
          // Stop mutator thread before creating the instruction object and
          // installing code.
          // Mutator thread may not run code while we are creating the
          // instruction object, since the creation of instruction object
          // changes code page access permissions (makes them temporary not
          // executable).
          {
            CheckIfBackgroundCompilerIsBeingStopped();
            SafepointOperationScope safepoint_scope(thread());
            // Do not Garbage collect during this stage and instead allow the
            // heap to grow.
            NoHeapGrowthControlScope no_growth_control;
            CheckIfBackgroundCompilerIsBeingStopped();
            *result =
                FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
          }
        }
      }
      // Exit the loop and the function with the correct result value.
      done = true;
    } else {
      // We bailed out or we encountered an error.
      const Error& error = Error::Handle(thread()->sticky_error());

      if (error.raw() == Object::branch_offset_error().raw()) {
        // Compilation failed due to an out of range branch offset in the
        // assembler. We try again (done = false) with far branches enabled.
        done = false;
        ASSERT(!use_far_branches);
        use_far_branches = true;
      } else if (error.raw() == Object::speculative_inlining_error().raw()) {
        // Can only happen with precompilation.
        UNREACHABLE();
      } else {
        // If the error isn't due to an out of range branch offset, we don't
        // try again (done = true).
        if (FLAG_trace_bailout) {
          THR_Print("%s\n", error.ToErrorCString());
        }
        done = true;
      }

      // If is is not a background compilation, clear the error if it was not a
      // real error, but just a bailout. If we're it a background compilation
      // this will be dealt with in the caller.
      if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() &&
          (LanguageError::Cast(error).kind() == Report::kBailout)) {
        thread()->clear_sticky_error();
      }
    }
  }
  return result->raw();
}

static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
                                        const Function& function,
                                        bool optimized,
                                        intptr_t osr_id) {
  ASSERT(!FLAG_precompiled_mode);
  ASSERT(!optimized || function.WasCompiled());
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Thread* const thread = Thread::Current();
    Isolate* const isolate = thread->isolate();
    StackZone stack_zone(thread);
    Zone* const zone = stack_zone.GetZone();
    const bool trace_compiler =
        FLAG_trace_compiler || (FLAG_trace_optimizing_compiler && optimized);
    Timer per_compile_timer(trace_compiler, "Compilation time");
    per_compile_timer.Start();

    ParsedFunction* parsed_function = new (zone)
        ParsedFunction(thread, Function::ZoneHandle(zone, function.raw()));
    if (trace_compiler) {
      const intptr_t token_size =
          function.end_token_pos().Pos() - function.token_pos().Pos();
      THR_Print("Compiling %s%sfunction %s: '%s' @ token %s, size %" Pd "\n",
                (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                (optimized ? "optimized " : ""),
                (Compiler::IsBackgroundCompilation() ? "(background)" : ""),
                function.ToFullyQualifiedCString(),
                function.token_pos().ToCString(), token_size);
    }
    INC_STAT(thread, num_functions_compiled, 1);
    if (optimized) {
      INC_STAT(thread, num_functions_optimized, 1);
    }
    // Makes sure no classes are loaded during parsing in background.
    const intptr_t loading_invalidation_gen_at_start =
        isolate->loading_invalidation_gen();
    {
      HANDLESCOPE(thread);
      const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed);
      pipeline->ParseFunction(parsed_function);
      const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed);
      INC_STAT(thread, num_func_tokens_compiled,
               num_tokens_after - num_tokens_before);
    }

    CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id);

    if (Compiler::IsBackgroundCompilation()) {
      ASSERT(function.is_background_optimizable());
      if (isolate->IsTopLevelParsing() ||
          (loading_invalidation_gen_at_start !=
           isolate->loading_invalidation_gen())) {
        // Loading occured while parsing. We need to abort here because state
        // changed while compiling.
        Compiler::AbortBackgroundCompilation(
            DeoptId::kNone,
            "Invalidated state during parsing because of script loading");
      }
    }

    const Code& result = Code::Handle(helper.Compile(pipeline));

    if (!result.IsNull()) {
      if (!optimized) {
        function.SetWasCompiled(true);
      }
    } else {
      if (Compiler::IsBackgroundCompilation()) {
        // Try again later, background compilation may abort because of
        // state change during compilation.
        if (FLAG_trace_compiler) {
          THR_Print("Aborted background compilation: %s\n",
                    function.ToFullyQualifiedCString());
        }
        {
          // If it was a bailout, then disable optimization.
          Error& error = Error::Handle();
          // We got an error during compilation.
          error = thread->sticky_error();
          thread->clear_sticky_error();

          if (error.raw() == Object::background_compilation_error().raw()) {
            if (FLAG_trace_compiler) {
              THR_Print(
                  "--> disabling background optimizations for '%s' (will "
                  "try to re-compile on isolate thread again)\n",
                  function.ToFullyQualifiedCString());
            }

            // Ensure we don't attempt to re-compile the function on the
            // background compiler.
            function.set_is_background_optimizable(false);

            // Trigger another optimization soon on the main thread.
            function.SetUsageCounter(optimized
                                         ? FLAG_optimization_counter_threshold
                                         : FLAG_compilation_counter_threshold);
          } else if ((error.IsLanguageError() &&
                      LanguageError::Cast(error).kind() == Report::kBailout) ||
                     error.IsUnhandledException()) {
            if (FLAG_trace_compiler) {
              THR_Print("--> disabling optimizations for '%s'\n",
                        function.ToFullyQualifiedCString());
            }
            function.SetIsOptimizable(false);
          }
        }
        return Error::null();
      }
      if (optimized) {
        // Optimizer bailed out. Disable optimizations and never try again.
        if (trace_compiler) {
          THR_Print("--> disabling optimizations for '%s'\n",
                    function.ToFullyQualifiedCString());
        } else if (FLAG_trace_failed_optimization_attempts) {
          THR_Print("Cannot optimize: %s\n",
                    function.ToFullyQualifiedCString());
        }
        function.SetIsOptimizable(false);
        return Error::null();
      } else {
        ASSERT(!optimized);
        // Encountered error.
        Error& error = Error::Handle();
        // We got an error during compilation.
        error = thread->sticky_error();
        thread->clear_sticky_error();
        // The non-optimizing compiler can get an unhandled exception
        // due to OOM or Stack overflow errors, it should not however
        // bail out.
        ASSERT(error.IsUnhandledException() ||
               (error.IsLanguageError() &&
                LanguageError::Cast(error).kind() != Report::kBailout));
        return error.raw();
      }
      UNREACHABLE();
    }

    per_compile_timer.Stop();

    if (trace_compiler) {
      THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                function.ToFullyQualifiedCString(),
                Code::Handle(function.CurrentCode()).PayloadStart(),
                Code::Handle(function.CurrentCode()).Size(),
                per_compile_timer.TotalElapsedTime());
    }

#if !defined(PRODUCT)
    isolate->debugger()->NotifyCompilation(function);
#endif

    if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
      Disassembler::DisassembleCode(function, result, optimized);
    } else if (FLAG_disassemble_optimized && optimized &&
               FlowGraphPrinter::ShouldPrint(function)) {
      Disassembler::DisassembleCode(function, result, true);
    }

    return result.raw();
  } else {
    Thread* const thread = Thread::Current();
    StackZone stack_zone(thread);
    Error& error = Error::Handle();
    // We got an error during compilation or it is a bailout from background
    // compilation (e.g., during parsing with EnsureIsFinalized).
    error = thread->sticky_error();
    thread->clear_sticky_error();
    if (error.raw() == Object::background_compilation_error().raw()) {
      // Exit compilation, retry it later.
      if (FLAG_trace_bailout) {
        THR_Print("Aborted background compilation: %s\n",
                  function.ToFullyQualifiedCString());
      }
      return Object::null();
    }
    // Do not attempt to optimize functions that can cause errors.
    function.set_is_optimizable(false);
    return error.raw();
  }
  UNREACHABLE();
  return Object::null();
}

static RawError* ParseFunctionHelper(CompilationPipeline* pipeline,
                                     const Function& function,
                                     bool optimized,
                                     intptr_t osr_id) {
  ASSERT(!FLAG_precompiled_mode);
  ASSERT(!optimized || function.WasCompiled());
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Thread* const thread = Thread::Current();
    StackZone stack_zone(thread);
    Zone* const zone = stack_zone.GetZone();
    const bool trace_compiler =
        FLAG_trace_compiler || (FLAG_trace_optimizing_compiler && optimized);

    if (trace_compiler) {
      const intptr_t token_size =
          function.end_token_pos().Pos() - function.token_pos().Pos();
      THR_Print("Parsing %s%sfunction %s: '%s' @ token %s, size %" Pd "\n",
                (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                (optimized ? "optimized " : ""),
                (Compiler::IsBackgroundCompilation() ? "(background)" : ""),
                function.ToFullyQualifiedCString(),
                function.token_pos().ToCString(), token_size);
    }
    ParsedFunction* parsed_function = new (zone)
        ParsedFunction(thread, Function::ZoneHandle(zone, function.raw()));
    pipeline->ParseFunction(parsed_function);
// For now we just walk thru the AST nodes and in DEBUG mode we print
// them otherwise just skip through them, this will be need to be
// wired to generate the IR format.
#if !defined(PRODUCT)
#if defined(DEBUG)
    AstPrinter ast_printer(true);
#else
    AstPrinter ast_printer(false);
#endif  // defined(DEBUG).
    ast_printer.PrintFunctionNodes(*parsed_function);
#endif  // !defined(PRODUCT).
    return Error::null();
  } else {
    Thread* const thread = Thread::Current();
    StackZone stack_zone(thread);
    Error& error = Error::Handle();
    // We got an error during compilation or it is a bailout from background
    // compilation (e.g., during parsing with EnsureIsFinalized).
    error = thread->sticky_error();
    thread->clear_sticky_error();
    // Unoptimized compilation or precompilation may encounter compile-time
    // errors, but regular optimized compilation should not.
    ASSERT(!optimized);
    return error.raw();
  }
  UNREACHABLE();
  return Error::null();
}

RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
    !defined(TARGET_ARCH_IA32)
  if (FLAG_precompiled_mode) {
    return Precompiler::CompileFunction(
        /* precompiler = */ NULL, thread, thread->zone(), function);
  }
#endif

  Isolate* isolate = thread->isolate();

#if !defined(PRODUCT)
  VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
  TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
#endif  // !defined(PRODUCT)

  if (!isolate->compilation_allowed()) {
    FATAL3("Precompilation missed function %s (%s, %s)\n",
           function.ToLibNamePrefixedQualifiedCString(),
           function.token_pos().ToCString(),
           Function::KindToCString(function.kind()));
  }

  CompilationPipeline* pipeline =
      CompilationPipeline::New(thread->zone(), function);

  return CompileFunctionHelper(pipeline, function,
                               /* optimized = */ false, kNoOSRDeoptId);
}

RawError* Compiler::ParseFunction(Thread* thread, const Function& function) {
  Isolate* isolate = thread->isolate();
#if !defined(PRODUCT)
  VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
  TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function);
#endif  // !defined(PRODUCT)

  if (!isolate->compilation_allowed()) {
    FATAL3("Precompilation missed function %s (%s, %s)\n",
           function.ToLibNamePrefixedQualifiedCString(),
           function.token_pos().ToCString(),
           Function::KindToCString(function.kind()));
  }

  CompilationPipeline* pipeline =
      CompilationPipeline::New(thread->zone(), function);

  return ParseFunctionHelper(pipeline, function,
                             /* optimized = */ false, kNoOSRDeoptId);
}

RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
                                          const Function& function) {
  if (function.unoptimized_code() != Object::null()) {
    return Error::null();
  }
  Code& original_code = Code::ZoneHandle(thread->zone());
  if (function.HasCode()) {
    original_code = function.CurrentCode();
  }
  CompilationPipeline* pipeline =
      CompilationPipeline::New(thread->zone(), function);
  const Object& result = Object::Handle(
      CompileFunctionHelper(pipeline, function, false, /* not optimized */
                            kNoOSRDeoptId));
  if (result.IsError()) {
    return Error::Cast(result).raw();
  }
  // Since CompileFunctionHelper replaces the current code, re-attach the
  // the original code if the function was already compiled.
  if (!original_code.IsNull() && result.raw() == function.CurrentCode() &&
      !original_code.IsDisabled()) {
    function.AttachCode(original_code);
  }
  ASSERT(function.unoptimized_code() != Object::null());
  ASSERT(function.unoptimized_code() == result.raw());
  if (FLAG_trace_compiler) {
    THR_Print("Ensure unoptimized code for %s\n", function.ToCString());
  }
  return Error::null();
}

RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
                                              const Function& function,
                                              intptr_t osr_id) {
#if !defined(PRODUCT)
  VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
  const char* event_name;
  if (osr_id != kNoOSRDeoptId) {
    event_name = "CompileFunctionOptimizedOSR";
  } else if (IsBackgroundCompilation()) {
    event_name = "CompileFunctionOptimizedBackground";
  } else {
    event_name = "CompileFunctionOptimized";
  }
  // TODO(alexmarkov): Consider adding a separate event for unoptimized
  // compilation triggered from interpreter
  TIMELINE_FUNCTION_COMPILATION_DURATION(thread, event_name, function);
#endif  // !defined(PRODUCT)

  // If running with interpreter, do the unoptimized compilation first.
  const bool optimized = !FLAG_enable_interpreter || function.WasCompiled();

  // If we are in the optimizing in the mutator/Dart thread, then
  // this is either an OSR compilation or background compilation is
  // not currently allowed.
  ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) ||
         !FLAG_background_compilation ||
         BackgroundCompiler::IsDisabled(Isolate::Current()) ||
         !function.is_background_optimizable());
  CompilationPipeline* pipeline =
      CompilationPipeline::New(thread->zone(), function);
  return CompileFunctionHelper(pipeline, function, optimized, osr_id);
}

// This is only used from unit tests.
RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) {
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    // Non-optimized code generator.
    DartCompilationPipeline pipeline;
    CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
    helper.Compile(&pipeline);
    if (FLAG_disassemble) {
      Code& code = Code::Handle(parsed_function->function().CurrentCode());
      Disassembler::DisassembleCode(parsed_function->function(), code, false);
    }
    return Error::null();
  } else {
    Error& error = Error::Handle();
    Thread* thread = Thread::Current();
    // We got an error during compilation.
    error = thread->sticky_error();
    thread->clear_sticky_error();
    return error.raw();
  }
  UNREACHABLE();
  return Error::null();
}

void Compiler::ComputeLocalVarDescriptors(const Code& code) {
  ASSERT(!code.is_optimized());
  const Function& function = Function::Handle(code.function());
  if (FLAG_enable_interpreter && function.Bytecode() == code.raw()) {
    // TODO(regis): Kernel bytecode does not yet provide var descriptors.
    ASSERT(code.var_descriptors() == Object::null());
    code.set_var_descriptors(Object::empty_var_descriptors());
    return;
  }
  ParsedFunction* parsed_function = new ParsedFunction(
      Thread::Current(), Function::ZoneHandle(function.raw()));
  ASSERT(code.var_descriptors() == Object::null());
  // IsIrregexpFunction have eager var descriptors generation.
  ASSERT(!function.IsIrregexpFunction());
  // In background compilation, parser can produce 'errors": bailouts
  // if state changed while compiling in background.
  CompilerState state(Thread::Current());
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    ZoneGrowableArray<const ICData*>* ic_data_array =
        new ZoneGrowableArray<const ICData*>();
    ZoneGrowableArray<intptr_t>* context_level_array =
        new ZoneGrowableArray<intptr_t>();

    if (!UseKernelFrontEndFor(parsed_function)) {
      Parser::ParseFunction(parsed_function);
      parsed_function->AllocateVariables();
      FlowGraphBuilder builder(
          *parsed_function, *ic_data_array, context_level_array,
          /* not inlining */ NULL, Compiler::kNoOSRDeoptId);
      builder.BuildGraph();
    } else {
      parsed_function->EnsureKernelScopes();
      kernel::FlowGraphBuilder builder(
          parsed_function, ic_data_array, context_level_array,
          /* not inlining */ NULL, false, Compiler::kNoOSRDeoptId);
      builder.BuildGraph();
    }

    const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
        parsed_function->node_sequence()->scope()->GetVarDescriptors(
            function, context_level_array));
    ASSERT(!var_descs.IsNull());
    code.set_var_descriptors(var_descs);
  } else {
    // Only possible with background compilation.
    ASSERT(Compiler::IsBackgroundCompilation());
  }
}

RawError* Compiler::CompileAllFunctions(const Class& cls) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Object& result = Object::Handle(zone);
  Array& functions = Array::Handle(zone, cls.functions());
  Function& func = Function::Handle(zone);
  // Class dynamic lives in the vm isolate. Its array fields cannot be set to
  // an empty array.
  if (functions.IsNull()) {
    ASSERT(cls.IsDynamicClass());
    return Error::null();
  }
  // Compile all the regular functions.
  for (int i = 0; i < functions.Length(); i++) {
    func ^= functions.At(i);
    ASSERT(!func.IsNull());
    if (!func.HasCode() &&
        !func.is_abstract() && !func.IsRedirectingFactory()) {
      if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
          func.HasOptionalParameters()) {
        // Skipping optional parameters in mixin application.
        continue;
      }
      result = CompileFunction(thread, func);
      if (result.IsError()) {
        return Error::Cast(result).raw();
      }
      ASSERT(!result.IsNull());
    }
  }
  return Error::null();
}

RawError* Compiler::ParseAllFunctions(const Class& cls) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Error& error = Error::Handle(zone);
  Array& functions = Array::Handle(zone, cls.functions());
  Function& func = Function::Handle(zone);
  // Class dynamic lives in the vm isolate. Its array fields cannot be set to
  // an empty array.
  if (functions.IsNull()) {
    ASSERT(cls.IsDynamicClass());
    return error.raw();
  }
  // Compile all the regular functions.
  for (int i = 0; i < functions.Length(); i++) {
    func ^= functions.At(i);
    ASSERT(!func.IsNull());
    if (!func.is_abstract() && !func.IsRedirectingFactory()) {
      if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
          func.HasOptionalParameters()) {
        // Skipping optional parameters in mixin application.
        continue;
      }
      error = ParseFunction(thread, func);
      if (!error.IsNull()) {
        return error.raw();
      }
      func.ClearICDataArray();
      func.ClearCode();
    }
  }
  return error.raw();
}

RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
    !defined(TARGET_ARCH_IA32)
  if (FLAG_precompiled_mode) {
    return Precompiler::EvaluateStaticInitializer(field);
  }
#endif
  ASSERT(field.is_static());
  // The VM sets the field's value to transiton_sentinel prior to
  // evaluating the initializer value.
  ASSERT(field.StaticValue() == Object::transition_sentinel().raw());
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Thread* const thread = Thread::Current();
    NoOOBMessageScope no_msg_scope(thread);
    NoReloadScope no_reload_scope(thread->isolate(), thread);
    // Under lazy compilation initializer has not yet been created, so create
    // it now, but don't bother remembering it because it won't be used again.
    ASSERT(!field.HasPrecompiledInitializer());
    {
#if !defined(PRODUCT)
      VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
      TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
                                "CompileStaticInitializer");
      if (tds.enabled()) {
        tds.SetNumArguments(1);
        tds.CopyArgument(0, "field", field.ToCString());
      }
#endif  // !defined(PRODUCT)

      StackZone stack_zone(thread);
      Zone* zone = stack_zone.GetZone();
      ParsedFunction* parsed_function;

      // Create a one-time-use function to evaluate the initializer and invoke
      // it immediately.
      if (field.kernel_offset() > 0) {
        parsed_function = kernel::ParseStaticFieldInitializer(zone, field);
      } else {
        parsed_function = Parser::ParseStaticFieldInitializer(field);
        parsed_function->AllocateVariables();
      }
      const Function& initializer = parsed_function->function();

      if (FLAG_enable_interpreter) {
        ASSERT(initializer.IsBytecodeAllowed(zone));
        if (!initializer.HasBytecode()) {
          RawError* error =
              kernel::BytecodeReader::ReadFunctionBytecode(thread, initializer);
          if (error != Error::null()) {
            return error;
          }
        }
        if (initializer.HasBytecode()) {
          return DartEntry::InvokeFunction(initializer, Object::empty_array());
        }
      }

      // Non-optimized code generator.
      DartCompilationPipeline pipeline;
      CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
      const Code& code = Code::Handle(helper.Compile(&pipeline));

      if (!code.IsNull()) {
        code.set_var_descriptors(Object::empty_var_descriptors());
        return DartEntry::InvokeFunction(initializer, Object::empty_array());
      }
    }
  }

  Thread* const thread = Thread::Current();
  StackZone zone(thread);
  const Error& error = Error::Handle(thread->zone(), thread->sticky_error());
  thread->clear_sticky_error();
  return error.raw();
}

RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
    !defined(TARGET_ARCH_IA32)
  if (FLAG_precompiled_mode) {
    return Precompiler::ExecuteOnce(fragment);
  }
#endif
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Thread* const thread = Thread::Current();

    // Don't allow message interrupts while executing constant
    // expressions.  They can cause bogus recursive compilation.
    NoOOBMessageScope no_msg_scope(thread);

    // Don't allow reload requests to come in.
    NoReloadScope no_reload_scope(thread->isolate(), thread);

    if (FLAG_trace_compiler) {
      THR_Print("compiling expression: ");
      if (FLAG_support_ast_printer) {
        AstPrinter ast_printer;
        ast_printer.PrintNode(fragment);
      }
    }

    // Create a dummy function object for the code generator.
    // The function needs to be associated with a named Class: the interface
    // Function fits the bill.
    const char* kEvalConst = "eval_const";
    const Function& func = Function::ZoneHandle(Function::New(
        String::Handle(Symbols::New(thread, kEvalConst)),
        RawFunction::kRegularFunction,
        true,   // static function
        false,  // not const function
        false,  // not abstract
        false,  // not external
        false,  // not native
        Class::Handle(Type::Handle(Type::DartFunctionType()).type_class()),
        fragment->token_pos()));

    func.set_result_type(Object::dynamic_type());
    func.set_num_fixed_parameters(0);
    func.SetNumOptionalParameters(0, true);
    // Manually generated AST, do not recompile.
    func.SetIsOptimizable(false);
    func.set_is_debuggable(false);

    // We compile the function here, even though InvokeFunction() below
    // would compile func automatically. We are checking fewer invariants
    // here.
    ParsedFunction* parsed_function = new ParsedFunction(thread, func);
    parsed_function->SetNodeSequence(fragment);
    fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp());
    fragment->scope()->AddVariable(parsed_function->current_context_var());
    parsed_function->AllocateVariables();

    // Non-optimized code generator.
    DartCompilationPipeline pipeline;
    CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
    const Code& code = Code::Handle(helper.Compile(&pipeline));
    if (!code.IsNull()) {
      code.set_var_descriptors(Object::empty_var_descriptors());
      const Object& result = PassiveObject::Handle(
          DartEntry::InvokeFunction(func, Object::empty_array()));
      return result.raw();
    }
  }

  Thread* const thread = Thread::Current();
  const Object& result = PassiveObject::Handle(thread->sticky_error());
  thread->clear_sticky_error();
  return result.raw();
}

void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) {
  if (FLAG_trace_compiler) {
    THR_Print("ABORT background compilation: %s\n", msg);
  }
#if !defined(PRODUCT)
  TimelineStream* stream = Timeline::GetCompilerStream();
  ASSERT(stream != NULL);
  TimelineEvent* event = stream->StartEvent();
  if (event != NULL) {
    event->Instant("AbortBackgroundCompilation");
    event->SetNumArguments(1);
    event->CopyArgument(0, "reason", msg);
    event->Complete();
  }
#endif  // !defined(PRODUCT)
  ASSERT(Compiler::IsBackgroundCompilation());
  Thread::Current()->long_jump_base()->Jump(
      deopt_id, Object::background_compilation_error());
}

// C-heap allocated background compilation queue element.
class QueueElement {
 public:
  explicit QueueElement(const Function& function)
      : next_(NULL), function_(function.raw()) {}

  virtual ~QueueElement() {
    next_ = NULL;
    function_ = Function::null();
  }

  RawFunction* Function() const { return function_; }

  void set_next(QueueElement* elem) { next_ = elem; }
  QueueElement* next() const { return next_; }

  RawObject* function() const { return function_; }
  RawObject** function_ptr() {
    return reinterpret_cast<RawObject**>(&function_);
  }

 private:
  QueueElement* next_;
  RawFunction* function_;

  DISALLOW_COPY_AND_ASSIGN(QueueElement);
};

// Allocated in C-heap. Handles both input and output of background compilation.
// It implements a FIFO queue, using Peek, Add, Remove operations.
class BackgroundCompilationQueue {
 public:
  BackgroundCompilationQueue() : first_(NULL), last_(NULL) {}
  virtual ~BackgroundCompilationQueue() { Clear(); }

  void VisitObjectPointers(ObjectPointerVisitor* visitor) {
    ASSERT(visitor != NULL);
    QueueElement* p = first_;
    while (p != NULL) {
      visitor->VisitPointer(p->function_ptr());
      p = p->next();
    }
  }

  bool IsEmpty() const { return first_ == NULL; }

  void Add(QueueElement* value) {
    ASSERT(value != NULL);
    ASSERT(value->next() == NULL);
    if (first_ == NULL) {
      first_ = value;
      ASSERT(last_ == NULL);
    } else {
      ASSERT(last_ != NULL);
      last_->set_next(value);
    }
    last_ = value;
    ASSERT(first_ != NULL && last_ != NULL);
  }

  QueueElement* Peek() const { return first_; }

  RawFunction* PeekFunction() const {
    QueueElement* e = Peek();
    if (e == NULL) {
      return Function::null();
    } else {
      return e->Function();
    }
  }

  QueueElement* Remove() {
    ASSERT(first_ != NULL);
    QueueElement* result = first_;
    first_ = first_->next();
    if (first_ == NULL) {
      last_ = NULL;
    }
    return result;
  }

  bool ContainsObj(const Object& obj) const {
    QueueElement* p = first_;
    while (p != NULL) {
      if (p->function() == obj.raw()) {
        return true;
      }
      p = p->next();
    }
    return false;
  }

  void Clear() {
    while (!IsEmpty()) {
      QueueElement* e = Remove();
      delete e;
    }
    ASSERT((first_ == NULL) && (last_ == NULL));
  }

 private:
  QueueElement* first_;
  QueueElement* last_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue);
};

BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
    : isolate_(isolate),
      queue_monitor_(new Monitor()),
      function_queue_(new BackgroundCompilationQueue()),
      done_monitor_(new Monitor()),
      running_(false),
      done_(true),
      disabled_depth_(0) {}

// Fields all deleted in ::Stop; here clear them.
BackgroundCompiler::~BackgroundCompiler() {
  delete queue_monitor_;
  delete function_queue_;
  delete done_monitor_;
}

void BackgroundCompiler::Run() {
  while (running_) {
    // Maybe something is already in the queue, check first before waiting
    // to be notified.
    bool result = Thread::EnterIsolateAsHelper(isolate_, Thread::kCompilerTask);
    ASSERT(result);
    {
      Thread* thread = Thread::Current();
      StackZone stack_zone(thread);
      Zone* zone = stack_zone.GetZone();
      HANDLESCOPE(thread);
      Function& function = Function::Handle(zone);
      {
        MonitorLocker ml(queue_monitor_);
        function = function_queue()->PeekFunction();
      }
      while (running_ && !function.IsNull() && !isolate_->IsTopLevelParsing()) {
        // Check that we have aggregated and cleared the stats.
        ASSERT(thread->compiler_stats()->IsCleared());
        Compiler::CompileOptimizedFunction(thread, function,
                                           Compiler::kNoOSRDeoptId);
#ifndef PRODUCT
        Isolate* isolate = thread->isolate();
        isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
        thread->compiler_stats()->Clear();
#endif  // PRODUCT

        QueueElement* qelem = NULL;
        {
          MonitorLocker ml(queue_monitor_);
          if (function_queue()->IsEmpty()) {
            // We are shutting down, queue was cleared.
            function = Function::null();
          } else {
            qelem = function_queue()->Remove();
            const Function& old = Function::Handle(qelem->Function());
            // If an optimizable method is not optimized, put it back on
            // the background queue (unless it was passed to foreground).
            if ((!old.HasOptimizedCode() && old.IsOptimizable()) ||
                FLAG_stress_test_background_compilation) {
              if (old.is_background_optimizable() &&
                  Compiler::CanOptimizeFunction(thread, old)) {
                QueueElement* repeat_qelem = new QueueElement(old);
                function_queue()->Add(repeat_qelem);
              }
            }
            function = function_queue()->PeekFunction();
          }
        }
        if (qelem != NULL) {
          delete qelem;
        }
      }
    }
    Thread::ExitIsolateAsHelper();
    {
      // Wait to be notified when the work queue is not empty.
      MonitorLocker ml(queue_monitor_);
      while ((function_queue()->IsEmpty() || isolate_->IsTopLevelParsing()) &&
             running_) {
        ml.Wait();
      }
    }
  }  // while running

  {
    // Notify that the thread is done.
    MonitorLocker ml_done(done_monitor_);
    done_ = true;
    ml_done.Notify();
  }
}

void BackgroundCompiler::CompileOptimized(const Function& function) {
  ASSERT(Thread::Current()->IsMutatorThread());
  // TODO(srdjan): Checking different strategy for collecting garbage
  // accumulated by background compiler.
  if (isolate_->heap()->NeedsGarbageCollection()) {
    isolate_->heap()->CollectMostGarbage();
  }
  {
    MonitorLocker ml(queue_monitor_);
    ASSERT(running_);
    if (function_queue()->ContainsObj(function)) {
      return;
    }
    QueueElement* elem = new QueueElement(function);
    function_queue()->Add(elem);
    ml.Notify();
  }
}

void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
  function_queue_->VisitObjectPointers(visitor);
}

class BackgroundCompilerTask : public ThreadPool::Task {
 public:
  explicit BackgroundCompilerTask(BackgroundCompiler* background_compiler)
      : background_compiler_(background_compiler) {}
  virtual ~BackgroundCompilerTask() {}

 private:
  virtual void Run() { background_compiler_->Run(); }

  BackgroundCompiler* background_compiler_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundCompilerTask);
};

void BackgroundCompiler::Start() {
  Thread* thread = Thread::Current();
  ASSERT(thread->IsMutatorThread());
  ASSERT(!thread->IsAtSafepoint());

  // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
  // compilation.
  Class& cls = Class::Handle(
      thread->zone(), Library::LookupCoreClass(Symbols::NoSuchMethodError()));
  ASSERT(!cls.IsNull());
  Error& error = Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread));
  ASSERT(error.IsNull());
  cls = Library::LookupCoreClass(Symbols::_Mint());
  ASSERT(!cls.IsNull());
  error = cls.EnsureIsFinalized(thread);
  ASSERT(error.IsNull());

  MonitorLocker ml(done_monitor_);
  if (running_ || !done_) return;
  running_ = true;
  done_ = false;
  bool task_started =
      Dart::thread_pool()->Run(new BackgroundCompilerTask(this));
  if (!task_started) {
    running_ = false;
    done_ = true;
  }
}

void BackgroundCompiler::Stop() {
  Thread* thread = Thread::Current();
  ASSERT(thread->IsMutatorThread());
  ASSERT(!thread->IsAtSafepoint());

  {
    MonitorLocker ml(queue_monitor_);
    running_ = false;
    function_queue_->Clear();
    ml.Notify();  // Stop waiting for the queue.
  }

  {
    MonitorLocker ml_done(done_monitor_);
    while (!done_) {
      ml_done.WaitWithSafepointCheck(thread);
    }
  }
}

void BackgroundCompiler::Enable() {
  disabled_depth_--;
  if (disabled_depth_ < 0) {
    FATAL("Mismatched number of calls to BackgroundCompiler::Enable/Disable.");
  }
}

void BackgroundCompiler::Disable() {
  Stop();
  disabled_depth_++;
}

bool BackgroundCompiler::IsDisabled() {
  return disabled_depth_ > 0;
}

#else  // DART_PRECOMPILED_RUNTIME

bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
  UNREACHABLE();
  return false;
}

CompilationPipeline* CompilationPipeline::New(Zone* zone,
                                              const Function& function) {
  UNREACHABLE();
  return NULL;
}

DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
  const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
  FATAL3("Precompilation missed function %s (%" Pd ", %s)\n",
         function.ToLibNamePrefixedQualifiedCString(),
         function.token_pos().value(),
         Function::KindToCString(function.kind()));
}

bool Compiler::IsBackgroundCompilation() {
  return false;
}

bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
  UNREACHABLE();
  return false;
}

RawError* Compiler::Compile(const Library& library, const Script& script) {
  FATAL1("Attempt to compile script %s", script.ToCString());
  return Error::null();
}

RawError* Compiler::CompileClass(const Class& cls) {
  FATAL1("Attempt to compile class %s", cls.ToCString());
  return Error::null();
}

RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
  FATAL1("Attempt to compile function %s", function.ToCString());
  return Error::null();
}

RawError* Compiler::ParseFunction(Thread* thread, const Function& function) {
  FATAL1("Attempt to parse function %s", function.ToCString());
  return Error::null();
}

RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
                                          const Function& function) {
  FATAL1("Attempt to compile function %s", function.ToCString());
  return Error::null();
}

RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
                                              const Function& function,
                                              intptr_t osr_id) {
  FATAL1("Attempt to compile function %s", function.ToCString());
  return Error::null();
}

RawError* Compiler::CompileParsedFunction(ParsedFunction* parsed_function) {
  FATAL1("Attempt to compile function %s",
         parsed_function->function().ToCString());
  return Error::null();
}

void Compiler::ComputeLocalVarDescriptors(const Code& code) {
  UNREACHABLE();
}

RawError* Compiler::CompileAllFunctions(const Class& cls) {
  FATAL1("Attempt to compile class %s", cls.ToCString());
  return Error::null();
}

RawError* Compiler::ParseAllFunctions(const Class& cls) {
  FATAL1("Attempt to parse class %s", cls.ToCString());
  return Error::null();
}

RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
  ASSERT(field.HasPrecompiledInitializer());
  const Function& initializer =
      Function::Handle(field.PrecompiledInitializer());
  return DartEntry::InvokeFunction(initializer, Object::empty_array());
}

RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
  UNREACHABLE();
  return Object::null();
}

void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) {
  UNREACHABLE();
}

void BackgroundCompiler::CompileOptimized(const Function& function) {
  UNREACHABLE();
}

void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
  UNREACHABLE();
}

void BackgroundCompiler::Start() {
  UNREACHABLE();
}

void BackgroundCompiler::Stop() {
  UNREACHABLE();
}

void BackgroundCompiler::Enable() {
  UNREACHABLE();
}

void BackgroundCompiler::Disable() {
  UNREACHABLE();
}

bool BackgroundCompiler::IsDisabled() {
  UNREACHABLE();
  return true;
}

#endif  // DART_PRECOMPILED_RUNTIME

}  // namespace dart
