diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index de660dd..c688a31 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -2444,7 +2444,7 @@
       }
       s->Write<uint32_t>(ic->ptr()->state_bits_);
 #if defined(TAG_IC_DATA)
-      s->Write<int32_t>(ic->ptr()->tag_);
+      s->Write<int32_t>(static_cast<int32_t>(ic->ptr()->tag_));
 #endif
     }
   }
@@ -2489,7 +2489,7 @@
       NOT_IN_PRECOMPILED(ic->ptr()->deopt_id_ = d->Read<int32_t>());
       ic->ptr()->state_bits_ = d->Read<int32_t>();
 #if defined(TAG_IC_DATA)
-      ic->ptr()->tag_ = d->Read<int32_t>();
+      ic->ptr()->tag_ = static_cast<ICData::Tag>(d->Read<int32_t>());
 #endif
     }
   }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 5b941df..d180a24 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -1649,7 +1649,7 @@
                           arguments_descriptor, deopt_id, num_args_tested,
                           ICData::kInstance));
 #if defined(TAG_IC_DATA)
-  ic_data.set_tag(Instruction::kInstanceCall);
+  ic_data.set_tag(ICData::Tag::kInstanceCall);
 #endif
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
@@ -1683,7 +1683,7 @@
                   deopt_id, num_args_tested, rebind_rule));
   ic_data.AddTarget(target);
 #if defined(TAG_IC_DATA)
-  ic_data.set_tag(Instruction::kStaticCall);
+  ic_data.set_tag(ICData::Tag::kStaticCall);
 #endif
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index b1ed153..0dd7ed5 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -320,9 +320,20 @@
     const ICData* result = ic_data_array[deopt_id_];
 #if defined(TAG_IC_DATA)
     if (result != NULL) {
-      if (result->tag() == -1) {
-        result->set_tag(tag());
-      } else if (result->tag() != tag()) {
+      ICData::Tag ic_data_tag = ICData::Tag::kUnknown;
+      switch (tag()) {
+        case kInstanceCall:
+          ic_data_tag = ICData::Tag::kInstanceCall;
+          break;
+        case kStaticCall:
+          ic_data_tag = ICData::Tag::kStaticCall;
+          break;
+        default:
+          UNREACHABLE();
+      }
+      if (result->tag() == ICData::Tag::kUnknown) {
+        result->set_tag(ic_data_tag);
+      } else if (result->tag() != ic_data_tag) {
         FATAL("ICData tag mismatch");
       }
     }
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index 09118db..5f6b3f9 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -75,6 +75,8 @@
   "cha.h",
   "compiler_pass.cc",
   "compiler_pass.h",
+  "frontend/bytecode_reader.cc",
+  "frontend/bytecode_reader.h",
   "frontend/flow_graph_builder.cc",
   "frontend/flow_graph_builder.h",
   "frontend/kernel_binary_flowgraph.cc",
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
new file mode 100644
index 0000000..b3ed8a3
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -0,0 +1,612 @@
+// Copyright (c) 2018, 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/frontend/bytecode_reader.h"
+
+#include "vm/bootstrap.h"
+#include "vm/code_descriptors.h"
+#include "vm/compiler/assembler/disassembler_kbc.h"
+#include "vm/dart_entry.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_USE_INTERPRETER)
+
+#define Z (zone_)
+#define H (translation_helper_)
+#define T (type_translator_)
+#define I Isolate::Current()
+
+namespace dart {
+
+DEFINE_FLAG(bool, dump_kernel_bytecode, false, "Dump kernel bytecode");
+
+namespace kernel {
+
+BytecodeMetadataHelper::BytecodeMetadataHelper(KernelReaderHelper* helper,
+                                               TypeTranslator* type_translator,
+                                               ActiveClass* active_class)
+    : MetadataHelper(helper, tag(), /* precompiler_only = */ false),
+      type_translator_(*type_translator),
+      active_class_(active_class) {}
+
+void BytecodeMetadataHelper::ReadMetadata(const Function& function) {
+  const intptr_t node_offset = function.kernel_offset();
+  const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+  if (md_offset < 0) {
+    return;
+  }
+
+  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
+                              md_offset);
+
+  // Create object pool and read pool entries.
+  const intptr_t obj_count = helper_->reader_.ReadListLength();
+  const ObjectPool& pool =
+      ObjectPool::Handle(helper_->zone_, ObjectPool::New(obj_count));
+  ReadPoolEntries(function, function, pool, 0);
+
+  // Read bytecode and attach to function.
+  const Code& bytecode = Code::Handle(helper_->zone_, ReadBytecode(pool));
+  function.AttachBytecode(bytecode);
+
+  // Read exceptions table.
+  ReadExceptionsTable(bytecode);
+
+  if (FLAG_dump_kernel_bytecode) {
+    KernelBytecodeDisassembler::Disassemble(function);
+  }
+
+  // Read closures.
+  Function& closure = Function::Handle(helper_->zone_);
+  Code& closure_bytecode = Code::Handle(helper_->zone_);
+  intptr_t num_closures = helper_->ReadListLength();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    intptr_t closure_index = helper_->ReadUInt();
+    ASSERT(closure_index < obj_count);
+    closure ^= pool.ObjectAt(closure_index);
+
+    // Read closure bytecode and attach to closure function.
+    closure_bytecode = ReadBytecode(pool);
+    closure.AttachBytecode(closure_bytecode);
+
+    // Read closure exceptions table.
+    ReadExceptionsTable(closure_bytecode);
+
+    if (FLAG_dump_kernel_bytecode) {
+      KernelBytecodeDisassembler::Disassemble(closure);
+    }
+  }
+}
+
+intptr_t BytecodeMetadataHelper::ReadPoolEntries(const Function& function,
+                                                 const Function& inner_function,
+                                                 const ObjectPool& pool,
+                                                 intptr_t from_index) {
+  // These enums and the code below reading the constant pool from kernel must
+  // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
+  enum ConstantPoolTag {
+    kInvalid,
+    kNull,
+    kString,
+    kInt,
+    kDouble,
+    kBool,
+    kArgDesc,
+    kICData,
+    kStaticICData,
+    kField,
+    kFieldOffset,
+    kClass,
+    kTypeArgumentsFieldOffset,
+    kTearOff,
+    kType,
+    kTypeArguments,
+    kList,
+    kInstance,
+    kSymbol,
+    kTypeArgumentsForInstanceAllocation,
+    kContextOffset,
+    kClosureFunction,
+    kEndClosureFunctionScope,
+    kNativeEntry,
+    kSubtypeTestCache,
+  };
+
+  enum InvocationKind {
+    method,  // x.foo(...) or foo(...)
+    getter,  // x.foo
+    setter   // x.foo = ...
+  };
+
+  Object& obj = Object::Handle(helper_->zone_);
+  Object& elem = Object::Handle(helper_->zone_);
+  Array& array = Array::Handle(helper_->zone_);
+  Field& field = Field::Handle(helper_->zone_);
+  Class& cls = Class::Handle(helper_->zone_);
+  String& name = String::Handle(helper_->zone_);
+  TypeArguments& type_args = TypeArguments::Handle(helper_->zone_);
+  const intptr_t obj_count = pool.Length();
+  for (intptr_t i = from_index; i < obj_count; ++i) {
+    const intptr_t tag = helper_->ReadTag();
+    switch (tag) {
+      case ConstantPoolTag::kInvalid:
+        UNREACHABLE();
+      case ConstantPoolTag::kNull:
+        obj = Object::null();
+        break;
+      case ConstantPoolTag::kString:
+        obj = H.DartString(helper_->ReadStringReference()).raw();
+        ASSERT(obj.IsString());
+        obj = H.Canonicalize(String::Cast(obj));
+        break;
+      case ConstantPoolTag::kInt: {
+        uint32_t low_bits = helper_->ReadUInt32();
+        int64_t value = helper_->ReadUInt32();
+        value = (value << 32) | low_bits;
+        obj = Integer::New(value);
+      } break;
+      case ConstantPoolTag::kDouble: {
+        uint32_t low_bits = helper_->ReadUInt32();
+        uint64_t bits = helper_->ReadUInt32();
+        bits = (bits << 32) | low_bits;
+        double value = bit_cast<double, uint64_t>(bits);
+        obj = Double::New(value);
+      } break;
+      case ConstantPoolTag::kBool:
+        if (helper_->ReadUInt() == 1) {
+          obj = Bool::True().raw();
+        } else {
+          obj = Bool::False().raw();
+        }
+        break;
+      case ConstantPoolTag::kArgDesc: {
+        intptr_t num_arguments = helper_->ReadUInt();
+        intptr_t num_type_args = helper_->ReadUInt();
+        intptr_t num_arg_names = helper_->ReadListLength();
+        if (num_arg_names == 0) {
+          obj = ArgumentsDescriptor::New(num_type_args, num_arguments);
+        } else {
+          array = Array::New(num_arg_names);
+          for (intptr_t j = 0; j < num_arg_names; j++) {
+            array.SetAt(j, H.DartSymbolPlain(helper_->ReadStringReference()));
+          }
+          obj = ArgumentsDescriptor::New(num_type_args, num_arguments, array);
+        }
+      } break;
+      case ConstantPoolTag::kICData: {
+        InvocationKind kind = static_cast<InvocationKind>(helper_->ReadByte());
+        if (kind == InvocationKind::getter) {
+          name = helper_->ReadNameAsGetterName().raw();
+        } else if (kind == InvocationKind::setter) {
+          name = helper_->ReadNameAsSetterName().raw();
+        } else {
+          ASSERT(kind == InvocationKind::method);
+          name = helper_->ReadNameAsMethodName().raw();
+        }
+        intptr_t arg_desc_index = helper_->ReadUInt();
+        ASSERT(arg_desc_index < i);
+        array ^= pool.ObjectAt(arg_desc_index);
+        // TODO(regis): Should num_args_tested be explicitly provided?
+        obj = ICData::New(function, name,
+                          array,  // Arguments descriptor.
+                          Thread::kNoDeoptId, 1 /* num_args_tested */,
+                          ICData::RebindRule::kInstance);
+#if defined(TAG_IC_DATA)
+        ICData::Cast(obj).set_tag(ICData::Tag::kInstanceCall);
+#endif
+      } break;
+      case ConstantPoolTag::kStaticICData: {
+        InvocationKind kind = static_cast<InvocationKind>(helper_->ReadByte());
+        NameIndex target = helper_->ReadCanonicalNameReference();
+        if (H.IsConstructor(target)) {
+          name = H.DartConstructorName(target).raw();
+          elem = H.LookupConstructorByKernelConstructor(target);
+        } else if (H.IsField(target)) {
+          if (kind == InvocationKind::getter) {
+            name = H.DartGetterName(target).raw();
+          } else if (kind == InvocationKind::setter) {
+            name = H.DartSetterName(target).raw();
+          } else {
+            ASSERT(kind == InvocationKind::method);
+            UNIMPLEMENTED();  // TODO(regis): Revisit.
+          }
+          field = H.LookupFieldByKernelField(target);
+          cls = field.Owner();
+          elem = cls.LookupFunctionAllowPrivate(name);
+        } else {
+          if ((kind == InvocationKind::method) && H.IsGetter(target)) {
+            UNIMPLEMENTED();  // TODO(regis): Revisit.
+          }
+          name = H.DartProcedureName(target).raw();
+          elem = H.LookupStaticMethodByKernelProcedure(target);
+        }
+        ASSERT(elem.IsFunction());
+        intptr_t arg_desc_index = helper_->ReadUInt();
+        ASSERT(arg_desc_index < i);
+        array ^= pool.ObjectAt(arg_desc_index);
+        obj = ICData::New(function, name,
+                          array,  // Arguments descriptor.
+                          Thread::kNoDeoptId, 0 /* num_args_tested */,
+                          ICData::RebindRule::kStatic);
+        ICData::Cast(obj).AddTarget(Function::Cast(elem));
+#if defined(TAG_IC_DATA)
+        ICData::Cast(obj).set_tag(ICData::Tag::kStaticCall);
+#endif
+      } break;
+      case ConstantPoolTag::kField:
+        obj = H.LookupFieldByKernelField(helper_->ReadCanonicalNameReference());
+        ASSERT(obj.IsField());
+        break;
+      case ConstantPoolTag::kFieldOffset:
+        obj = H.LookupFieldByKernelField(helper_->ReadCanonicalNameReference());
+        ASSERT(obj.IsField());
+        obj = Smi::New(Field::Cast(obj).Offset() / kWordSize);
+        break;
+      case ConstantPoolTag::kClass:
+        obj = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
+        ASSERT(obj.IsClass());
+        break;
+      case ConstantPoolTag::kTypeArgumentsFieldOffset:
+        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
+        obj = Smi::New(cls.type_arguments_field_offset() / kWordSize);
+        break;
+      case ConstantPoolTag::kTearOff:
+        obj = H.LookupStaticMethodByKernelProcedure(
+            helper_->ReadCanonicalNameReference());
+        ASSERT(obj.IsFunction());
+        obj = Function::Cast(obj).ImplicitClosureFunction();
+        ASSERT(obj.IsFunction());
+        obj = Function::Cast(obj).ImplicitStaticClosure();
+        ASSERT(obj.IsInstance());
+        obj = H.Canonicalize(Instance::Cast(obj));
+        break;
+      case ConstantPoolTag::kType:
+        obj = type_translator_.BuildType().raw();
+        ASSERT(obj.IsAbstractType());
+        break;
+      case ConstantPoolTag::kTypeArguments:
+        obj = type_translator_.BuildTypeArguments(helper_->ReadListLength())
+                  .raw();
+        ASSERT(obj.IsNull() || obj.IsTypeArguments());
+        break;
+      case ConstantPoolTag::kList: {
+        obj = type_translator_.BuildType().raw();
+        ASSERT(obj.IsAbstractType());
+        const intptr_t length = helper_->ReadListLength();
+        array = Array::New(length, AbstractType::Cast(obj));
+        for (intptr_t j = 0; j < length; j++) {
+          intptr_t elem_index = helper_->ReadUInt();
+          ASSERT(elem_index < i);
+          elem = pool.ObjectAt(elem_index);
+          array.SetAt(j, elem);
+        }
+        obj = H.Canonicalize(Array::Cast(array));
+        ASSERT(!obj.IsNull());
+      } break;
+      case ConstantPoolTag::kInstance: {
+        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
+        obj = Instance::New(cls, Heap::kOld);
+        intptr_t type_args_index = helper_->ReadUInt();
+        ASSERT(type_args_index < i);
+        type_args ^= pool.ObjectAt(type_args_index);
+        if (!type_args.IsNull()) {
+          Instance::Cast(obj).SetTypeArguments(type_args);
+        }
+        intptr_t num_fields = helper_->ReadUInt();
+        for (intptr_t j = 0; j < num_fields; j++) {
+          NameIndex field_name = helper_->ReadCanonicalNameReference();
+          ASSERT(H.IsField(field_name));
+          field = H.LookupFieldByKernelField(field_name);
+          intptr_t elem_index = helper_->ReadUInt();
+          ASSERT(elem_index < i);
+          elem = pool.ObjectAt(elem_index);
+          Instance::Cast(obj).SetField(field, elem);
+        }
+        obj = H.Canonicalize(Instance::Cast(obj));
+      } break;
+      case ConstantPoolTag::kSymbol:
+        obj = H.DartSymbolPlain(helper_->ReadStringReference()).raw();
+        ASSERT(String::Cast(obj).IsSymbol());
+        break;
+      case ConstantPoolTag::kTypeArgumentsForInstanceAllocation: {
+        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
+        obj =
+            type_translator_
+                .BuildInstantiatedTypeArguments(cls, helper_->ReadListLength())
+                .raw();
+        ASSERT(obj.IsNull() || obj.IsTypeArguments());
+      } break;
+      case ConstantPoolTag::kContextOffset: {
+        intptr_t index = helper_->ReadUInt();
+        if (index == 0) {
+          obj = Smi::New(Context::parent_offset() / kWordSize);
+        } else {
+          obj = Smi::New(Context::variable_offset(index - 1) / kWordSize);
+        }
+      } break;
+      case ConstantPoolTag::kClosureFunction: {
+        name = H.DartSymbolPlain(helper_->ReadStringReference()).raw();
+        const Function& closure = Function::Handle(
+            helper_->zone_,
+            Function::NewClosureFunction(name, inner_function,
+                                         TokenPosition::kNoSource));
+
+        FunctionNodeHelper function_node_helper(helper_);
+        function_node_helper.ReadUntilExcluding(
+            FunctionNodeHelper::kTypeParameters);
+        type_translator_.LoadAndSetupTypeParameters(
+            active_class_, closure, helper_->ReadListLength(), closure);
+        function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
+
+        // Scope remains opened until ConstantPoolTag::kEndClosureFunctionScope.
+        ActiveTypeParametersScope scope(
+            active_class_, &closure,
+            TypeArguments::Handle(helper_->zone_, closure.type_parameters()),
+            helper_->zone_);
+
+        function_node_helper.ReadUntilExcluding(
+            FunctionNodeHelper::kPositionalParameters);
+
+        intptr_t required_parameter_count =
+            function_node_helper.required_parameter_count_;
+        intptr_t total_parameter_count =
+            function_node_helper.total_parameter_count_;
+
+        intptr_t positional_parameter_count = helper_->ReadListLength();
+
+        intptr_t named_parameter_count =
+            total_parameter_count - positional_parameter_count;
+
+        const intptr_t extra_parameters = 1;
+        closure.set_num_fixed_parameters(extra_parameters +
+                                         required_parameter_count);
+        if (named_parameter_count > 0) {
+          closure.SetNumOptionalParameters(named_parameter_count, false);
+        } else {
+          closure.SetNumOptionalParameters(
+              positional_parameter_count - required_parameter_count, true);
+        }
+        intptr_t parameter_count = extra_parameters + total_parameter_count;
+        closure.set_parameter_types(Array::Handle(
+            helper_->zone_, Array::New(parameter_count, Heap::kOld)));
+        closure.set_parameter_names(Array::Handle(
+            helper_->zone_, Array::New(parameter_count, Heap::kOld)));
+
+        intptr_t pos = 0;
+        closure.SetParameterTypeAt(pos, AbstractType::dynamic_type());
+        closure.SetParameterNameAt(pos, Symbols::ClosureParameter());
+        pos++;
+
+        const Library& lib =
+            Library::Handle(helper_->zone_, active_class_->klass->library());
+        for (intptr_t j = 0; j < positional_parameter_count; ++j, ++pos) {
+          VariableDeclarationHelper helper(helper_);
+          helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
+          const AbstractType& type = type_translator_.BuildVariableType();
+          Tag tag = helper_->ReadTag();  // read (first part of) initializer.
+          if (tag == kSomething) {
+            helper_->SkipExpression();  // read (actual) initializer.
+          }
+
+          closure.SetParameterTypeAt(pos, type);
+          closure.SetParameterNameAt(pos,
+                                     H.DartIdentifier(lib, helper.name_index_));
+        }
+
+        intptr_t named_parameter_count_check = helper_->ReadListLength();
+        ASSERT(named_parameter_count_check == named_parameter_count);
+        for (intptr_t j = 0; j < named_parameter_count; ++j, ++pos) {
+          VariableDeclarationHelper helper(helper_);
+          helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
+          const AbstractType& type = type_translator_.BuildVariableType();
+          Tag tag = helper_->ReadTag();  // read (first part of) initializer.
+          if (tag == kSomething) {
+            helper_->SkipExpression();  // read (actual) initializer.
+          }
+
+          closure.SetParameterTypeAt(pos, type);
+          closure.SetParameterNameAt(pos,
+                                     H.DartIdentifier(lib, helper.name_index_));
+        }
+
+        function_node_helper.SetJustRead(FunctionNodeHelper::kNamedParameters);
+
+        const AbstractType& return_type = type_translator_.BuildVariableType();
+        closure.set_result_type(return_type);
+        function_node_helper.SetJustRead(FunctionNodeHelper::kReturnType);
+        // The closure has no body.
+        function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
+
+        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+        pool.SetObjectAt(i, closure);
+
+        // Continue reading the constant pool entries inside the opened
+        // ActiveTypeParametersScope until the scope gets closed by a
+        // kEndClosureFunctionScope tag, in which case control returns here.
+        i = ReadPoolEntries(function, closure, pool, i + 1);
+        // Pool entry at index i has been set to null, because it was a
+        // kEndClosureFunctionScope.
+        ASSERT(pool.ObjectAt(i) == Object::null());
+        continue;
+      }
+      case ConstantPoolTag::kEndClosureFunctionScope: {
+        // Entry is not used and set to null.
+        obj = Object::null();
+        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+        pool.SetObjectAt(i, obj);
+        return i;  // The caller will close the scope.
+      } break;
+      case ConstantPoolTag::kNativeEntry: {
+        name = H.DartString(helper_->ReadStringReference()).raw();
+        obj = NativeEntry(function, name);
+      } break;
+      case ConstantPoolTag::kSubtypeTestCache: {
+        obj = SubtypeTestCache::New();
+      } break;
+      default:
+        UNREACHABLE();
+    }
+    pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+    pool.SetObjectAt(i, obj);
+  }
+  // Return the index of the last read pool entry.
+  return obj_count - 1;
+}
+
+RawCode* BytecodeMetadataHelper::ReadBytecode(const ObjectPool& pool) {
+  intptr_t size = helper_->reader_.ReadUInt();
+  intptr_t offset = helper_->reader_.offset();
+  const uint8_t* data = helper_->reader_.BufferAt(offset);
+  helper_->reader_.set_offset(offset + size);
+
+  // Create and return code object.
+  return Code::FinalizeBytecode(reinterpret_cast<const void*>(data), size,
+                                pool);
+}
+
+void BytecodeMetadataHelper::ReadExceptionsTable(const Code& bytecode) {
+  const intptr_t try_block_count = helper_->reader_.ReadListLength();
+  if (try_block_count > 0) {
+    const ObjectPool& pool =
+        ObjectPool::Handle(helper_->zone_, bytecode.object_pool());
+    AbstractType& handler_type = AbstractType::Handle(helper_->zone_);
+    Array& handler_types = Array::ZoneHandle(helper_->zone_);
+    DescriptorList* pc_descriptors_list =
+        new (helper_->zone_) DescriptorList(64);
+    ExceptionHandlerList* exception_handlers_list =
+        new (helper_->zone_) ExceptionHandlerList();
+
+    // Encoding of ExceptionsTable is described in
+    // pkg/vm/lib/bytecode/exceptions.dart.
+    for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
+      intptr_t outer_try_index_plus1 = helper_->reader_.ReadUInt();
+      intptr_t outer_try_index = outer_try_index_plus1 - 1;
+      intptr_t start_pc = helper_->reader_.ReadUInt();
+      intptr_t end_pc = helper_->reader_.ReadUInt();
+      intptr_t handler_pc = helper_->reader_.ReadUInt();
+      uint8_t flags = helper_->reader_.ReadByte();
+      const uint8_t kFlagNeedsStackTrace = 1 << 0;
+      const uint8_t kFlagIsSynthetic = 1 << 1;
+      const bool needs_stacktrace = (flags & kFlagNeedsStackTrace) != 0;
+      const bool is_generated = (flags & kFlagIsSynthetic) != 0;
+      intptr_t type_count = helper_->reader_.ReadListLength();
+      ASSERT(type_count > 0);
+      handler_types = Array::New(type_count, Heap::kOld);
+      for (intptr_t i = 0; i < type_count; i++) {
+        intptr_t type_index = helper_->reader_.ReadUInt();
+        ASSERT(type_index < pool.Length());
+        handler_type ^= pool.ObjectAt(type_index);
+        handler_types.SetAt(i, handler_type);
+      }
+      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, start_pc,
+                                         Thread::kNoDeoptId,
+                                         TokenPosition::kNoSource, try_index);
+      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc,
+                                         Thread::kNoDeoptId,
+                                         TokenPosition::kNoSource, -1);
+
+      exception_handlers_list->AddHandler(
+          try_index, outer_try_index, handler_pc, TokenPosition::kNoSource,
+          is_generated, handler_types, needs_stacktrace);
+    }
+    const PcDescriptors& descriptors = PcDescriptors::Handle(
+        helper_->zone_,
+        pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
+    bytecode.set_pc_descriptors(descriptors);
+    const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
+        helper_->zone_, exception_handlers_list->FinalizeExceptionHandlers(
+                            bytecode.PayloadStart()));
+    bytecode.set_exception_handlers(handlers);
+  } else {
+    bytecode.set_pc_descriptors(Object::empty_descriptors());
+    bytecode.set_exception_handlers(Object::empty_exception_handlers());
+  }
+}
+
+RawTypedData* BytecodeMetadataHelper::NativeEntry(const Function& function,
+                                                  const String& external_name) {
+  Zone* zone = helper_->zone_;
+  MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
+  // This list of recognized methods must be kept in sync with the list of
+  // methods handled specially by the NativeCall bytecode in the interpreter.
+  switch (kind) {
+    case MethodRecognizer::kObjectEquals:
+    case MethodRecognizer::kStringBaseLength:
+    case MethodRecognizer::kStringBaseIsEmpty:
+    case MethodRecognizer::kGrowableArrayLength:
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+    case MethodRecognizer::kTypedDataLength:
+    case MethodRecognizer::kClassIDgetID:
+    case MethodRecognizer::kGrowableArrayCapacity:
+    case MethodRecognizer::kListFactory:
+    case MethodRecognizer::kObjectArrayAllocate:
+    case MethodRecognizer::kLinkedHashMap_getIndex:
+    case MethodRecognizer::kLinkedHashMap_setIndex:
+    case MethodRecognizer::kLinkedHashMap_getData:
+    case MethodRecognizer::kLinkedHashMap_setData:
+    case MethodRecognizer::kLinkedHashMap_getHashMask:
+    case MethodRecognizer::kLinkedHashMap_setHashMask:
+    case MethodRecognizer::kLinkedHashMap_getUsedData:
+    case MethodRecognizer::kLinkedHashMap_setUsedData:
+    case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
+    case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+      break;
+    default:
+      kind = MethodRecognizer::kUnknown;
+  }
+  NativeFunctionWrapper trampoline = NULL;
+  NativeFunction native_function = NULL;
+  intptr_t argc_tag = 0;
+  if (kind == MethodRecognizer::kUnknown) {
+    if (FLAG_link_natives_lazily) {
+      trampoline = &NativeEntry::BootstrapNativeCallWrapper;
+      native_function =
+          reinterpret_cast<NativeFunction>(&NativeEntry::LinkNativeCall);
+    } else {
+      const Class& cls = Class::Handle(zone, function.Owner());
+      const Library& library = Library::Handle(zone, cls.library());
+      Dart_NativeEntryResolver resolver = library.native_entry_resolver();
+      const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
+      const int num_params =
+          NativeArguments::ParameterCountForResolution(function);
+      bool is_auto_scope = true;
+      native_function = NativeEntry::ResolveNative(library, external_name,
+                                                   num_params, &is_auto_scope);
+      ASSERT(native_function != NULL);  // TODO(regis): Should we throw instead?
+      if (is_bootstrap_native) {
+        trampoline = &NativeEntry::BootstrapNativeCallWrapper;
+      } else if (is_auto_scope) {
+        trampoline = &NativeEntry::AutoScopeNativeCallWrapper;
+      } else {
+        trampoline = &NativeEntry::NoScopeNativeCallWrapper;
+      }
+    }
+    argc_tag = NativeArguments::ComputeArgcTag(function);
+  }
+  // TODO(regis): Introduce a new VM class subclassing Object and containing
+  // these four untagged values.
+#ifdef ARCH_IS_32_BIT
+  const TypedData& native_entry = TypedData::Handle(
+      zone, TypedData::New(kTypedDataUint32ArrayCid, 4, Heap::kOld));
+  native_entry.SetUint32(0 << 2, static_cast<uint32_t>(kind));
+  native_entry.SetUint32(1 << 2, reinterpret_cast<uint32_t>(trampoline));
+  native_entry.SetUint32(2 << 2, reinterpret_cast<uint32_t>(native_function));
+  native_entry.SetUint32(3 << 2, static_cast<uint32_t>(argc_tag));
+#else
+  const TypedData& native_entry = TypedData::Handle(
+      zone, TypedData::New(kTypedDataUint64ArrayCid, 4, Heap::kOld));
+  native_entry.SetUint64(0 << 3, static_cast<uint64_t>(kind));
+  native_entry.SetUint64(1 << 3, reinterpret_cast<uint64_t>(trampoline));
+  native_entry.SetUint64(2 << 3, reinterpret_cast<uint64_t>(native_function));
+  native_entry.SetUint64(3 << 3, static_cast<uint64_t>(argc_tag));
+#endif
+  return native_entry.raw();
+}
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
new file mode 100644
index 0000000..e32cf14
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
+#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
+
+#include "vm/compiler/frontend/kernel_translation_helper.h"
+#include "vm/object.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_USE_INTERPRETER)
+
+namespace dart {
+namespace kernel {
+
+// Helper class which provides access to bytecode metadata.
+class BytecodeMetadataHelper : public MetadataHelper {
+ public:
+  static const char* tag() { return "vm.bytecode"; }
+
+  explicit BytecodeMetadataHelper(KernelReaderHelper* helper,
+                                  TypeTranslator* type_translator,
+                                  ActiveClass* active_class);
+
+  void ReadMetadata(const Function& function);
+
+ private:
+  // Returns the index of the last read pool entry.
+  intptr_t ReadPoolEntries(const Function& function,
+                           const Function& inner_function,
+                           const ObjectPool& pool,
+                           intptr_t from_index);
+  RawCode* ReadBytecode(const ObjectPool& pool);
+  void ReadExceptionsTable(const Code& bytecode);
+  RawTypedData* NativeEntry(const Function& function,
+                            const String& external_name);
+
+  TypeTranslator& type_translator_;
+  ActiveClass* const active_class_;
+};
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 3a8f5cb..037f497 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4,10 +4,8 @@
 
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 
-#include "vm/bootstrap.h"
-#include "vm/code_descriptors.h"
 #include "vm/compiler/aot/precompiler.h"
-#include "vm/compiler/assembler/disassembler_kbc.h"
+#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/prologue_builder.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
@@ -19,11 +17,6 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
-
-#if defined(DART_USE_INTERPRETER)
-DEFINE_FLAG(bool, dump_kernel_bytecode, false, "Dump kernel bytecode");
-#endif  // defined(DART_USE_INTERPRETER)
-
 namespace kernel {
 
 #define Z (zone_)
@@ -63,738 +56,6 @@
   return !FLAG_precompiled_mode || !attrs.has_dynamic_invocations;
 }
 
-DirectCallMetadataHelper::DirectCallMetadataHelper(KernelReaderHelper* helper)
-    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
-
-bool DirectCallMetadataHelper::ReadMetadata(intptr_t node_offset,
-                                            NameIndex* target_name,
-                                            bool* check_receiver_for_null) {
-  intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
-  if (md_offset < 0) {
-    return false;
-  }
-
-  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
-                              md_offset);
-
-  *target_name = helper_->ReadCanonicalNameReference();
-  *check_receiver_for_null = helper_->ReadBool();
-  return true;
-}
-
-DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForPropertyGet(
-    intptr_t node_offset) {
-  NameIndex kernel_name;
-  bool check_receiver_for_null = false;
-  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
-    return DirectCallMetadata(Function::null_function(), false);
-  }
-
-  if (H.IsProcedure(kernel_name) && !H.IsGetter(kernel_name)) {
-    // Tear-off. Use method extractor as direct call target.
-    const String& method_name = H.DartMethodName(kernel_name);
-    const Function& target_method = Function::ZoneHandle(
-        helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
-    const String& getter_name = H.DartGetterName(kernel_name);
-    return DirectCallMetadata(
-        Function::ZoneHandle(helper_->zone_,
-                             target_method.GetMethodExtractor(getter_name)),
-        check_receiver_for_null);
-  } else {
-    const String& getter_name = H.DartGetterName(kernel_name);
-    const Function& target = Function::ZoneHandle(
-        helper_->zone_, H.LookupMethodByMember(kernel_name, getter_name));
-    ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction());
-    return DirectCallMetadata(target, check_receiver_for_null);
-  }
-}
-
-DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForPropertySet(
-    intptr_t node_offset) {
-  NameIndex kernel_name;
-  bool check_receiver_for_null = false;
-  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
-    return DirectCallMetadata(Function::null_function(), false);
-  }
-
-  const String& method_name = H.DartSetterName(kernel_name);
-  const Function& target = Function::ZoneHandle(
-      helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
-  ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction());
-
-  return DirectCallMetadata(target, check_receiver_for_null);
-}
-
-DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForMethodInvocation(
-    intptr_t node_offset) {
-  NameIndex kernel_name;
-  bool check_receiver_for_null = false;
-  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
-    return DirectCallMetadata(Function::null_function(), false);
-  }
-
-  const String& method_name = H.DartProcedureName(kernel_name);
-  const Function& target = Function::ZoneHandle(
-      helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
-
-  return DirectCallMetadata(target, check_receiver_for_null);
-}
-
-bool ProcedureAttributesMetadataHelper::ReadMetadata(
-    intptr_t node_offset,
-    ProcedureAttributesMetadata* metadata) {
-  intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
-  if (md_offset < 0) {
-    return false;
-  }
-
-  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
-                              md_offset);
-
-  const int kDynamicUsesBit = 1 << 0;
-  const int kNonThisUsesBit = 1 << 1;
-  const int kTearOffUsesBit = 1 << 2;
-
-  const uint8_t flags = helper_->ReadByte();
-  metadata->has_dynamic_invocations =
-      (flags & kDynamicUsesBit) == kDynamicUsesBit;
-  metadata->has_non_this_uses = (flags & kNonThisUsesBit) == kNonThisUsesBit;
-  metadata->has_tearoff_uses = (flags & kTearOffUsesBit) == kTearOffUsesBit;
-  return true;
-}
-
-ProcedureAttributesMetadataHelper::ProcedureAttributesMetadataHelper(
-    KernelReaderHelper* helper)
-    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
-
-ProcedureAttributesMetadata
-ProcedureAttributesMetadataHelper::GetProcedureAttributes(
-    intptr_t node_offset) {
-  ProcedureAttributesMetadata metadata;
-  ReadMetadata(node_offset, &metadata);
-  return metadata;
-}
-
-InferredTypeMetadataHelper::InferredTypeMetadataHelper(
-    KernelReaderHelper* helper)
-    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
-
-InferredTypeMetadata InferredTypeMetadataHelper::GetInferredType(
-    intptr_t node_offset) {
-  const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
-  if (md_offset < 0) {
-    return InferredTypeMetadata(kDynamicCid, true);
-  }
-
-  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
-                              md_offset);
-
-  const NameIndex kernel_name = helper_->ReadCanonicalNameReference();
-  const bool nullable = helper_->ReadBool();
-
-  if (H.IsRoot(kernel_name)) {
-    return InferredTypeMetadata(kDynamicCid, nullable);
-  }
-
-  const Class& klass =
-      Class::Handle(helper_->zone_, H.LookupClassByKernelClass(kernel_name));
-  ASSERT(!klass.IsNull());
-
-  intptr_t cid = klass.id();
-  if (cid == kClosureCid) {
-    // VM uses more specific function types and doesn't expect instances of
-    // _Closure class, so inferred _Closure class doesn't make sense for the VM.
-    cid = kDynamicCid;
-  }
-
-  return InferredTypeMetadata(cid, nullable);
-}
-
-#if defined(DART_USE_INTERPRETER)
-
-BytecodeMetadataHelper::BytecodeMetadataHelper(KernelReaderHelper* helper,
-                                               TypeTranslator* type_translator,
-                                               ActiveClass* active_class)
-    : MetadataHelper(helper, tag(), /* precompiler_only = */ false),
-      type_translator_(*type_translator),
-      active_class_(active_class) {}
-
-void BytecodeMetadataHelper::ReadMetadata(const Function& function) {
-  const intptr_t node_offset = function.kernel_offset();
-  const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
-  if (md_offset < 0) {
-    return;
-  }
-
-  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
-                              md_offset);
-
-  // Create object pool and read pool entries.
-  const intptr_t obj_count = helper_->reader_.ReadListLength();
-  const ObjectPool& pool =
-      ObjectPool::Handle(helper_->zone_, ObjectPool::New(obj_count));
-  ReadPoolEntries(function, function, pool, 0);
-
-  // Read bytecode and attach to function.
-  const Code& bytecode = Code::Handle(helper_->zone_, ReadBytecode(pool));
-  function.AttachBytecode(bytecode);
-
-  // Read exceptions table.
-  ReadExceptionsTable(bytecode);
-
-  if (FLAG_dump_kernel_bytecode) {
-    KernelBytecodeDisassembler::Disassemble(function);
-  }
-
-  // Read closures.
-  Function& closure = Function::Handle(helper_->zone_);
-  Code& closure_bytecode = Code::Handle(helper_->zone_);
-  intptr_t num_closures = helper_->ReadListLength();
-  for (intptr_t i = 0; i < num_closures; i++) {
-    intptr_t closure_index = helper_->ReadUInt();
-    ASSERT(closure_index < obj_count);
-    closure ^= pool.ObjectAt(closure_index);
-
-    // Read closure bytecode and attach to closure function.
-    closure_bytecode = ReadBytecode(pool);
-    closure.AttachBytecode(closure_bytecode);
-
-    // Read closure exceptions table.
-    ReadExceptionsTable(closure_bytecode);
-
-    if (FLAG_dump_kernel_bytecode) {
-      KernelBytecodeDisassembler::Disassemble(closure);
-    }
-  }
-}
-
-intptr_t BytecodeMetadataHelper::ReadPoolEntries(const Function& function,
-                                                 const Function& inner_function,
-                                                 const ObjectPool& pool,
-                                                 intptr_t from_index) {
-  // These enums and the code below reading the constant pool from kernel must
-  // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
-  enum ConstantPoolTag {
-    kInvalid,
-    kNull,
-    kString,
-    kInt,
-    kDouble,
-    kBool,
-    kArgDesc,
-    kICData,
-    kStaticICData,
-    kField,
-    kFieldOffset,
-    kClass,
-    kTypeArgumentsFieldOffset,
-    kTearOff,
-    kType,
-    kTypeArguments,
-    kList,
-    kInstance,
-    kSymbol,
-    kTypeArgumentsForInstanceAllocation,
-    kContextOffset,
-    kClosureFunction,
-    kEndClosureFunctionScope,
-    kNativeEntry,
-    kSubtypeTestCache,
-  };
-
-  enum InvocationKind {
-    method,  // x.foo(...) or foo(...)
-    getter,  // x.foo
-    setter   // x.foo = ...
-  };
-
-  Object& obj = Object::Handle(helper_->zone_);
-  Object& elem = Object::Handle(helper_->zone_);
-  Array& array = Array::Handle(helper_->zone_);
-  Field& field = Field::Handle(helper_->zone_);
-  Class& cls = Class::Handle(helper_->zone_);
-  String& name = String::Handle(helper_->zone_);
-  TypeArguments& type_args = TypeArguments::Handle(helper_->zone_);
-  const intptr_t obj_count = pool.Length();
-  for (intptr_t i = from_index; i < obj_count; ++i) {
-    const intptr_t tag = helper_->ReadTag();
-    switch (tag) {
-      case ConstantPoolTag::kInvalid:
-        UNREACHABLE();
-      case ConstantPoolTag::kNull:
-        obj = Object::null();
-        break;
-      case ConstantPoolTag::kString:
-        obj = H.DartString(helper_->ReadStringReference()).raw();
-        ASSERT(obj.IsString());
-        obj = H.Canonicalize(String::Cast(obj));
-        break;
-      case ConstantPoolTag::kInt: {
-        uint32_t low_bits = helper_->ReadUInt32();
-        int64_t value = helper_->ReadUInt32();
-        value = (value << 32) | low_bits;
-        obj = Integer::New(value);
-      } break;
-      case ConstantPoolTag::kDouble: {
-        uint32_t low_bits = helper_->ReadUInt32();
-        uint64_t bits = helper_->ReadUInt32();
-        bits = (bits << 32) | low_bits;
-        double value = bit_cast<double, uint64_t>(bits);
-        obj = Double::New(value);
-      } break;
-      case ConstantPoolTag::kBool:
-        if (helper_->ReadUInt() == 1) {
-          obj = Bool::True().raw();
-        } else {
-          obj = Bool::False().raw();
-        }
-        break;
-      case ConstantPoolTag::kArgDesc: {
-        intptr_t num_arguments = helper_->ReadUInt();
-        intptr_t num_type_args = helper_->ReadUInt();
-        intptr_t num_arg_names = helper_->ReadListLength();
-        if (num_arg_names == 0) {
-          obj = ArgumentsDescriptor::New(num_type_args, num_arguments);
-        } else {
-          array = Array::New(num_arg_names);
-          for (intptr_t j = 0; j < num_arg_names; j++) {
-            array.SetAt(j, H.DartSymbolPlain(helper_->ReadStringReference()));
-          }
-          obj = ArgumentsDescriptor::New(num_type_args, num_arguments, array);
-        }
-      } break;
-      case ConstantPoolTag::kICData: {
-        InvocationKind kind = static_cast<InvocationKind>(helper_->ReadByte());
-        if (kind == InvocationKind::getter) {
-          name = helper_->ReadNameAsGetterName().raw();
-        } else if (kind == InvocationKind::setter) {
-          name = helper_->ReadNameAsSetterName().raw();
-        } else {
-          ASSERT(kind == InvocationKind::method);
-          name = helper_->ReadNameAsMethodName().raw();
-        }
-        intptr_t arg_desc_index = helper_->ReadUInt();
-        ASSERT(arg_desc_index < i);
-        array ^= pool.ObjectAt(arg_desc_index);
-        // TODO(regis): Should num_args_tested be explicitly provided?
-        obj = ICData::New(function, name,
-                          array,  // Arguments descriptor.
-                          Thread::kNoDeoptId, 1 /* num_args_tested */,
-                          ICData::RebindRule::kInstance);
-#if defined(TAG_IC_DATA)
-        ICData::Cast(obj).set_tag(Instruction::kInstanceCall);
-#endif
-      } break;
-      case ConstantPoolTag::kStaticICData: {
-        InvocationKind kind = static_cast<InvocationKind>(helper_->ReadByte());
-        NameIndex target = helper_->ReadCanonicalNameReference();
-        if (H.IsConstructor(target)) {
-          name = H.DartConstructorName(target).raw();
-          elem = H.LookupConstructorByKernelConstructor(target);
-        } else if (H.IsField(target)) {
-          if (kind == InvocationKind::getter) {
-            name = H.DartGetterName(target).raw();
-          } else if (kind == InvocationKind::setter) {
-            name = H.DartSetterName(target).raw();
-          } else {
-            ASSERT(kind == InvocationKind::method);
-            UNIMPLEMENTED();  // TODO(regis): Revisit.
-          }
-          field = H.LookupFieldByKernelField(target);
-          cls = field.Owner();
-          elem = cls.LookupFunctionAllowPrivate(name);
-        } else {
-          if ((kind == InvocationKind::method) && H.IsGetter(target)) {
-            UNIMPLEMENTED();  // TODO(regis): Revisit.
-          }
-          name = H.DartProcedureName(target).raw();
-          elem = H.LookupStaticMethodByKernelProcedure(target);
-        }
-        ASSERT(elem.IsFunction());
-        intptr_t arg_desc_index = helper_->ReadUInt();
-        ASSERT(arg_desc_index < i);
-        array ^= pool.ObjectAt(arg_desc_index);
-        obj = ICData::New(function, name,
-                          array,  // Arguments descriptor.
-                          Thread::kNoDeoptId, 0 /* num_args_tested */,
-                          ICData::RebindRule::kStatic);
-        ICData::Cast(obj).AddTarget(Function::Cast(elem));
-#if defined(TAG_IC_DATA)
-        ICData::Cast(obj).set_tag(Instruction::kStaticCall);
-#endif
-      } break;
-      case ConstantPoolTag::kField:
-        obj = H.LookupFieldByKernelField(helper_->ReadCanonicalNameReference());
-        ASSERT(obj.IsField());
-        break;
-      case ConstantPoolTag::kFieldOffset:
-        obj = H.LookupFieldByKernelField(helper_->ReadCanonicalNameReference());
-        ASSERT(obj.IsField());
-        obj = Smi::New(Field::Cast(obj).Offset() / kWordSize);
-        break;
-      case ConstantPoolTag::kClass:
-        obj = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
-        ASSERT(obj.IsClass());
-        break;
-      case ConstantPoolTag::kTypeArgumentsFieldOffset:
-        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
-        obj = Smi::New(cls.type_arguments_field_offset() / kWordSize);
-        break;
-      case ConstantPoolTag::kTearOff:
-        obj = H.LookupStaticMethodByKernelProcedure(
-            helper_->ReadCanonicalNameReference());
-        ASSERT(obj.IsFunction());
-        obj = Function::Cast(obj).ImplicitClosureFunction();
-        ASSERT(obj.IsFunction());
-        obj = Function::Cast(obj).ImplicitStaticClosure();
-        ASSERT(obj.IsInstance());
-        obj = H.Canonicalize(Instance::Cast(obj));
-        break;
-      case ConstantPoolTag::kType:
-        obj = type_translator_.BuildType().raw();
-        ASSERT(obj.IsAbstractType());
-        break;
-      case ConstantPoolTag::kTypeArguments:
-        obj = type_translator_.BuildTypeArguments(helper_->ReadListLength())
-                  .raw();
-        ASSERT(obj.IsNull() || obj.IsTypeArguments());
-        break;
-      case ConstantPoolTag::kList: {
-        obj = type_translator_.BuildType().raw();
-        ASSERT(obj.IsAbstractType());
-        const intptr_t length = helper_->ReadListLength();
-        array = Array::New(length, AbstractType::Cast(obj));
-        for (intptr_t j = 0; j < length; j++) {
-          intptr_t elem_index = helper_->ReadUInt();
-          ASSERT(elem_index < i);
-          elem = pool.ObjectAt(elem_index);
-          array.SetAt(j, elem);
-        }
-        obj = H.Canonicalize(Array::Cast(array));
-        ASSERT(!obj.IsNull());
-      } break;
-      case ConstantPoolTag::kInstance: {
-        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
-        obj = Instance::New(cls, Heap::kOld);
-        intptr_t type_args_index = helper_->ReadUInt();
-        ASSERT(type_args_index < i);
-        type_args ^= pool.ObjectAt(type_args_index);
-        if (!type_args.IsNull()) {
-          Instance::Cast(obj).SetTypeArguments(type_args);
-        }
-        intptr_t num_fields = helper_->ReadUInt();
-        for (intptr_t j = 0; j < num_fields; j++) {
-          NameIndex field_name = helper_->ReadCanonicalNameReference();
-          ASSERT(H.IsField(field_name));
-          field = H.LookupFieldByKernelField(field_name);
-          intptr_t elem_index = helper_->ReadUInt();
-          ASSERT(elem_index < i);
-          elem = pool.ObjectAt(elem_index);
-          Instance::Cast(obj).SetField(field, elem);
-        }
-        obj = H.Canonicalize(Instance::Cast(obj));
-      } break;
-      case ConstantPoolTag::kSymbol:
-        obj = H.DartSymbolPlain(helper_->ReadStringReference()).raw();
-        ASSERT(String::Cast(obj).IsSymbol());
-        break;
-      case ConstantPoolTag::kTypeArgumentsForInstanceAllocation: {
-        cls = H.LookupClassByKernelClass(helper_->ReadCanonicalNameReference());
-        obj =
-            type_translator_
-                .BuildInstantiatedTypeArguments(cls, helper_->ReadListLength())
-                .raw();
-        ASSERT(obj.IsNull() || obj.IsTypeArguments());
-      } break;
-      case ConstantPoolTag::kContextOffset: {
-        intptr_t index = helper_->ReadUInt();
-        if (index == 0) {
-          obj = Smi::New(Context::parent_offset() / kWordSize);
-        } else {
-          obj = Smi::New(Context::variable_offset(index - 1) / kWordSize);
-        }
-      } break;
-      case ConstantPoolTag::kClosureFunction: {
-        name = H.DartSymbolPlain(helper_->ReadStringReference()).raw();
-        const Function& closure = Function::Handle(
-            helper_->zone_,
-            Function::NewClosureFunction(name, inner_function,
-                                         TokenPosition::kNoSource));
-
-        FunctionNodeHelper function_node_helper(helper_);
-        function_node_helper.ReadUntilExcluding(
-            FunctionNodeHelper::kTypeParameters);
-        type_translator_.LoadAndSetupTypeParameters(
-            active_class_, closure, helper_->ReadListLength(), closure);
-        function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
-
-        // Scope remains opened until ConstantPoolTag::kEndClosureFunctionScope.
-        ActiveTypeParametersScope scope(
-            active_class_, &closure,
-            TypeArguments::Handle(helper_->zone_, closure.type_parameters()),
-            helper_->zone_);
-
-        function_node_helper.ReadUntilExcluding(
-            FunctionNodeHelper::kPositionalParameters);
-
-        intptr_t required_parameter_count =
-            function_node_helper.required_parameter_count_;
-        intptr_t total_parameter_count =
-            function_node_helper.total_parameter_count_;
-
-        intptr_t positional_parameter_count = helper_->ReadListLength();
-
-        intptr_t named_parameter_count =
-            total_parameter_count - positional_parameter_count;
-
-        const intptr_t extra_parameters = 1;
-        closure.set_num_fixed_parameters(extra_parameters +
-                                         required_parameter_count);
-        if (named_parameter_count > 0) {
-          closure.SetNumOptionalParameters(named_parameter_count, false);
-        } else {
-          closure.SetNumOptionalParameters(
-              positional_parameter_count - required_parameter_count, true);
-        }
-        intptr_t parameter_count = extra_parameters + total_parameter_count;
-        closure.set_parameter_types(Array::Handle(
-            helper_->zone_, Array::New(parameter_count, Heap::kOld)));
-        closure.set_parameter_names(Array::Handle(
-            helper_->zone_, Array::New(parameter_count, Heap::kOld)));
-
-        intptr_t pos = 0;
-        closure.SetParameterTypeAt(pos, AbstractType::dynamic_type());
-        closure.SetParameterNameAt(pos, Symbols::ClosureParameter());
-        pos++;
-
-        const Library& lib =
-            Library::Handle(helper_->zone_, active_class_->klass->library());
-        for (intptr_t j = 0; j < positional_parameter_count; ++j, ++pos) {
-          VariableDeclarationHelper helper(helper_);
-          helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
-          const AbstractType& type = type_translator_.BuildVariableType();
-          Tag tag = helper_->ReadTag();  // read (first part of) initializer.
-          if (tag == kSomething) {
-            helper_->SkipExpression();  // read (actual) initializer.
-          }
-
-          closure.SetParameterTypeAt(pos, type);
-          closure.SetParameterNameAt(pos,
-                                     H.DartIdentifier(lib, helper.name_index_));
-        }
-
-        intptr_t named_parameter_count_check = helper_->ReadListLength();
-        ASSERT(named_parameter_count_check == named_parameter_count);
-        for (intptr_t j = 0; j < named_parameter_count; ++j, ++pos) {
-          VariableDeclarationHelper helper(helper_);
-          helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
-          const AbstractType& type = type_translator_.BuildVariableType();
-          Tag tag = helper_->ReadTag();  // read (first part of) initializer.
-          if (tag == kSomething) {
-            helper_->SkipExpression();  // read (actual) initializer.
-          }
-
-          closure.SetParameterTypeAt(pos, type);
-          closure.SetParameterNameAt(pos,
-                                     H.DartIdentifier(lib, helper.name_index_));
-        }
-
-        function_node_helper.SetJustRead(FunctionNodeHelper::kNamedParameters);
-
-        const AbstractType& return_type = type_translator_.BuildVariableType();
-        closure.set_result_type(return_type);
-        function_node_helper.SetJustRead(FunctionNodeHelper::kReturnType);
-        // The closure has no body.
-        function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
-
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
-        pool.SetObjectAt(i, closure);
-
-        // Continue reading the constant pool entries inside the opened
-        // ActiveTypeParametersScope until the scope gets closed by a
-        // kEndClosureFunctionScope tag, in which case control returns here.
-        i = ReadPoolEntries(function, closure, pool, i + 1);
-        // Pool entry at index i has been set to null, because it was a
-        // kEndClosureFunctionScope.
-        ASSERT(pool.ObjectAt(i) == Object::null());
-        continue;
-      }
-      case ConstantPoolTag::kEndClosureFunctionScope: {
-        // Entry is not used and set to null.
-        obj = Object::null();
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
-        pool.SetObjectAt(i, obj);
-        return i;  // The caller will close the scope.
-      } break;
-      case ConstantPoolTag::kNativeEntry: {
-        name = H.DartString(helper_->ReadStringReference()).raw();
-        obj = NativeEntry(function, name);
-      } break;
-      case ConstantPoolTag::kSubtypeTestCache: {
-        obj = SubtypeTestCache::New();
-      } break;
-      default:
-        UNREACHABLE();
-    }
-    pool.SetTypeAt(i, ObjectPool::kTaggedObject);
-    pool.SetObjectAt(i, obj);
-  }
-  // Return the index of the last read pool entry.
-  return obj_count - 1;
-}
-
-RawCode* BytecodeMetadataHelper::ReadBytecode(const ObjectPool& pool) {
-  intptr_t size = helper_->reader_.ReadUInt();
-  intptr_t offset = helper_->reader_.offset();
-  const uint8_t* data = helper_->reader_.BufferAt(offset);
-  helper_->reader_.set_offset(offset + size);
-
-  // Create and return code object.
-  return Code::FinalizeBytecode(reinterpret_cast<const void*>(data), size,
-                                pool);
-}
-
-void BytecodeMetadataHelper::ReadExceptionsTable(const Code& bytecode) {
-  const intptr_t try_block_count = helper_->reader_.ReadListLength();
-  if (try_block_count > 0) {
-    const ObjectPool& pool =
-        ObjectPool::Handle(helper_->zone_, bytecode.object_pool());
-    AbstractType& handler_type = AbstractType::Handle(helper_->zone_);
-    Array& handler_types = Array::ZoneHandle(helper_->zone_);
-    DescriptorList* pc_descriptors_list =
-        new (helper_->zone_) DescriptorList(64);
-    ExceptionHandlerList* exception_handlers_list =
-        new (helper_->zone_) ExceptionHandlerList();
-
-    // Encoding of ExceptionsTable is described in
-    // pkg/vm/lib/bytecode/exceptions.dart.
-    for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
-      intptr_t outer_try_index_plus1 = helper_->reader_.ReadUInt();
-      intptr_t outer_try_index = outer_try_index_plus1 - 1;
-      intptr_t start_pc = helper_->reader_.ReadUInt();
-      intptr_t end_pc = helper_->reader_.ReadUInt();
-      intptr_t handler_pc = helper_->reader_.ReadUInt();
-      uint8_t flags = helper_->reader_.ReadByte();
-      const uint8_t kFlagNeedsStackTrace = 1 << 0;
-      const uint8_t kFlagIsSynthetic = 1 << 1;
-      const bool needs_stacktrace = (flags & kFlagNeedsStackTrace) != 0;
-      const bool is_generated = (flags & kFlagIsSynthetic) != 0;
-      intptr_t type_count = helper_->reader_.ReadListLength();
-      ASSERT(type_count > 0);
-      handler_types = Array::New(type_count, Heap::kOld);
-      for (intptr_t i = 0; i < type_count; i++) {
-        intptr_t type_index = helper_->reader_.ReadUInt();
-        ASSERT(type_index < pool.Length());
-        handler_type ^= pool.ObjectAt(type_index);
-        handler_types.SetAt(i, handler_type);
-      }
-      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, start_pc,
-                                         Thread::kNoDeoptId,
-                                         TokenPosition::kNoSource, try_index);
-      pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc,
-                                         Thread::kNoDeoptId,
-                                         TokenPosition::kNoSource, -1);
-
-      exception_handlers_list->AddHandler(
-          try_index, outer_try_index, handler_pc, TokenPosition::kNoSource,
-          is_generated, handler_types, needs_stacktrace);
-    }
-    const PcDescriptors& descriptors = PcDescriptors::Handle(
-        helper_->zone_,
-        pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
-    bytecode.set_pc_descriptors(descriptors);
-    const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
-        helper_->zone_, exception_handlers_list->FinalizeExceptionHandlers(
-                            bytecode.PayloadStart()));
-    bytecode.set_exception_handlers(handlers);
-  } else {
-    bytecode.set_pc_descriptors(Object::empty_descriptors());
-    bytecode.set_exception_handlers(Object::empty_exception_handlers());
-  }
-}
-
-RawTypedData* BytecodeMetadataHelper::NativeEntry(const Function& function,
-                                                  const String& external_name) {
-  Zone* zone = helper_->zone_;
-  MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
-  // This list of recognized methods must be kept in sync with the list of
-  // methods handled specially by the NativeCall bytecode in the interpreter.
-  switch (kind) {
-    case MethodRecognizer::kObjectEquals:
-    case MethodRecognizer::kStringBaseLength:
-    case MethodRecognizer::kStringBaseIsEmpty:
-    case MethodRecognizer::kGrowableArrayLength:
-    case MethodRecognizer::kObjectArrayLength:
-    case MethodRecognizer::kImmutableArrayLength:
-    case MethodRecognizer::kTypedDataLength:
-    case MethodRecognizer::kClassIDgetID:
-    case MethodRecognizer::kGrowableArrayCapacity:
-    case MethodRecognizer::kListFactory:
-    case MethodRecognizer::kObjectArrayAllocate:
-    case MethodRecognizer::kLinkedHashMap_getIndex:
-    case MethodRecognizer::kLinkedHashMap_setIndex:
-    case MethodRecognizer::kLinkedHashMap_getData:
-    case MethodRecognizer::kLinkedHashMap_setData:
-    case MethodRecognizer::kLinkedHashMap_getHashMask:
-    case MethodRecognizer::kLinkedHashMap_setHashMask:
-    case MethodRecognizer::kLinkedHashMap_getUsedData:
-    case MethodRecognizer::kLinkedHashMap_setUsedData:
-    case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
-    case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
-      break;
-    default:
-      kind = MethodRecognizer::kUnknown;
-  }
-  NativeFunctionWrapper trampoline = NULL;
-  NativeFunction native_function = NULL;
-  intptr_t argc_tag = 0;
-  if (kind == MethodRecognizer::kUnknown) {
-    if (FLAG_link_natives_lazily) {
-      trampoline = &NativeEntry::BootstrapNativeCallWrapper;
-      native_function =
-          reinterpret_cast<NativeFunction>(&NativeEntry::LinkNativeCall);
-    } else {
-      const Class& cls = Class::Handle(zone, function.Owner());
-      const Library& library = Library::Handle(zone, cls.library());
-      Dart_NativeEntryResolver resolver = library.native_entry_resolver();
-      const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
-      const int num_params =
-          NativeArguments::ParameterCountForResolution(function);
-      bool is_auto_scope = true;
-      native_function = NativeEntry::ResolveNative(library, external_name,
-                                                   num_params, &is_auto_scope);
-      ASSERT(native_function != NULL);  // TODO(regis): Should we throw instead?
-      if (is_bootstrap_native) {
-        trampoline = &NativeEntry::BootstrapNativeCallWrapper;
-      } else if (is_auto_scope) {
-        trampoline = &NativeEntry::AutoScopeNativeCallWrapper;
-      } else {
-        trampoline = &NativeEntry::NoScopeNativeCallWrapper;
-      }
-    }
-    argc_tag = NativeArguments::ComputeArgcTag(function);
-  }
-  // TODO(regis): Introduce a new VM class subclassing Object and containing
-  // these four untagged values.
-#ifdef ARCH_IS_32_BIT
-  const TypedData& native_entry = TypedData::Handle(
-      zone, TypedData::New(kTypedDataUint32ArrayCid, 4, Heap::kOld));
-  native_entry.SetUint32(0 << 2, static_cast<uint32_t>(kind));
-  native_entry.SetUint32(1 << 2, reinterpret_cast<uint32_t>(trampoline));
-  native_entry.SetUint32(2 << 2, reinterpret_cast<uint32_t>(native_function));
-  native_entry.SetUint32(3 << 2, static_cast<uint32_t>(argc_tag));
-#else
-  const TypedData& native_entry = TypedData::Handle(
-      zone, TypedData::New(kTypedDataUint64ArrayCid, 4, Heap::kOld));
-  native_entry.SetUint64(0 << 3, static_cast<uint64_t>(kind));
-  native_entry.SetUint64(1 << 3, reinterpret_cast<uint64_t>(trampoline));
-  native_entry.SetUint64(2 << 3, reinterpret_cast<uint64_t>(native_function));
-  native_entry.SetUint64(3 << 3, static_cast<uint64_t>(argc_tag));
-#endif
-  return native_entry.raw();
-}
-#endif  // defined(DART_USE_INTERPRETER)
-
 StreamingScopeBuilder::StreamingScopeBuilder(ParsedFunction* parsed_function)
     : result_(NULL),
       parsed_function_(parsed_function),
@@ -2428,456 +1689,6 @@
   }
 }
 
-TypeTranslator::TypeTranslator(KernelReaderHelper* helper,
-                               ActiveClass* active_class,
-                               bool finalize)
-    : helper_(helper),
-      translation_helper_(helper->translation_helper_),
-      active_class_(active_class),
-      type_parameter_scope_(NULL),
-      zone_(translation_helper_.zone()),
-      result_(AbstractType::Handle(translation_helper_.zone())),
-      finalize_(finalize) {}
-
-AbstractType& TypeTranslator::BuildType() {
-  BuildTypeInternal();
-
-  // We return a new `ZoneHandle` here on purpose: The intermediate language
-  // instructions do not make a copy of the handle, so we do it.
-  return AbstractType::ZoneHandle(Z, result_.raw());
-}
-
-AbstractType& TypeTranslator::BuildTypeWithoutFinalization() {
-  bool saved_finalize = finalize_;
-  finalize_ = false;
-  BuildTypeInternal();
-  finalize_ = saved_finalize;
-
-  // We return a new `ZoneHandle` here on purpose: The intermediate language
-  // instructions do not make a copy of the handle, so we do it.
-  return AbstractType::ZoneHandle(Z, result_.raw());
-}
-
-AbstractType& TypeTranslator::BuildVariableType() {
-  AbstractType& abstract_type = BuildType();
-
-  // We return a new `ZoneHandle` here on purpose: The intermediate language
-  // instructions do not make a copy of the handle, so we do it.
-  AbstractType& type = Type::ZoneHandle(Z);
-
-  if (abstract_type.IsMalformed()) {
-    type = AbstractType::dynamic_type().raw();
-  } else {
-    type = result_.raw();
-  }
-
-  return type;
-}
-
-void TypeTranslator::BuildTypeInternal(bool invalid_as_dynamic) {
-  Tag tag = helper_->ReadTag();
-  switch (tag) {
-    case kInvalidType:
-      if (invalid_as_dynamic) {
-        result_ = Object::dynamic_type().raw();
-      } else {
-        result_ = ClassFinalizer::NewFinalizedMalformedType(
-            Error::Handle(Z),  // No previous error.
-            Script::Handle(Z, Script::null()), TokenPosition::kNoSource,
-            "[InvalidType] in Kernel IR.");
-      }
-      break;
-    case kDynamicType:
-      result_ = Object::dynamic_type().raw();
-      break;
-    case kVoidType:
-      result_ = Object::void_type().raw();
-      break;
-    case kBottomType:
-      result_ =
-          Class::Handle(Z, I->object_store()->null_class()).CanonicalType();
-      break;
-    case kInterfaceType:
-      BuildInterfaceType(false);
-      break;
-    case kSimpleInterfaceType:
-      BuildInterfaceType(true);
-      break;
-    case kFunctionType:
-      BuildFunctionType(false);
-      break;
-    case kSimpleFunctionType:
-      BuildFunctionType(true);
-      break;
-    case kTypeParameterType:
-      BuildTypeParameterType();
-      break;
-    default:
-      helper_->ReportUnexpectedTag("type", tag);
-      UNREACHABLE();
-  }
-}
-
-void TypeTranslator::BuildInterfaceType(bool simple) {
-  // NOTE: That an interface type like `T<A, B>` is considered to be
-  // malformed iff `T` is malformed.
-  //   => We therefore ignore errors in `A` or `B`.
-
-  NameIndex klass_name =
-      helper_->ReadCanonicalNameReference();  // read klass_name.
-
-  intptr_t length;
-  if (simple) {
-    length = 0;
-  } else {
-    length = helper_->ReadListLength();  // read type_arguments list length.
-  }
-  const TypeArguments& type_arguments =
-      BuildTypeArguments(length);  // read type arguments.
-
-  Object& klass = Object::Handle(Z, H.LookupClassByKernelClass(klass_name));
-  result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource);
-  if (finalize_) {
-    ASSERT(active_class_->klass != NULL);
-    result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_);
-  }
-}
-
-void TypeTranslator::BuildFunctionType(bool simple) {
-  Function& signature_function = Function::ZoneHandle(
-      Z, Function::NewSignatureFunction(*active_class_->klass,
-                                        active_class_->enclosing != NULL
-                                            ? *active_class_->enclosing
-                                            : Function::Handle(Z),
-                                        TokenPosition::kNoSource));
-
-  // Suspend finalization of types inside this one. They will be finalized after
-  // the whole function type is constructed.
-  //
-  // TODO(31213): Test further when nested generic function types
-  // are supported by fasta.
-  bool finalize = finalize_;
-  finalize_ = false;
-
-  if (!simple) {
-    LoadAndSetupTypeParameters(active_class_, signature_function,
-                               helper_->ReadListLength(), signature_function);
-  }
-
-  ActiveTypeParametersScope scope(
-      active_class_, &signature_function,
-      TypeArguments::Handle(Z, signature_function.type_parameters()), Z);
-
-  intptr_t required_count;
-  intptr_t all_count;
-  intptr_t positional_count;
-  if (!simple) {
-    required_count = helper_->ReadUInt();  // read required parameter count.
-    all_count = helper_->ReadUInt();       // read total parameter count.
-    positional_count =
-        helper_->ReadListLength();  // read positional_parameters list length.
-  } else {
-    positional_count =
-        helper_->ReadListLength();  // read positional_parameters list length.
-    required_count = positional_count;
-    all_count = positional_count;
-  }
-
-  const Array& parameter_types =
-      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
-  signature_function.set_parameter_types(parameter_types);
-  const Array& parameter_names =
-      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
-  signature_function.set_parameter_names(parameter_names);
-
-  intptr_t pos = 0;
-  parameter_types.SetAt(pos, AbstractType::dynamic_type());
-  parameter_names.SetAt(pos, H.DartSymbolPlain("_receiver_"));
-  ++pos;
-  for (intptr_t i = 0; i < positional_count; ++i, ++pos) {
-    BuildTypeInternal();  // read ith positional parameter.
-    if (result_.IsMalformed()) {
-      result_ = AbstractType::dynamic_type().raw();
-    }
-    parameter_types.SetAt(pos, result_);
-    parameter_names.SetAt(pos, H.DartSymbolPlain("noname"));
-  }
-
-  // The additional first parameter is the receiver type (set to dynamic).
-  signature_function.set_num_fixed_parameters(1 + required_count);
-  signature_function.SetNumOptionalParameters(
-      all_count - required_count, positional_count > required_count);
-
-  if (!simple) {
-    const intptr_t named_count =
-        helper_->ReadListLength();  // read named_parameters list length.
-    for (intptr_t i = 0; i < named_count; ++i, ++pos) {
-      // read string reference (i.e. named_parameters[i].name).
-      String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
-      BuildTypeInternal();  // read named_parameters[i].type.
-      if (result_.IsMalformed()) {
-        result_ = AbstractType::dynamic_type().raw();
-      }
-      parameter_types.SetAt(pos, result_);
-      parameter_names.SetAt(pos, name);
-    }
-  }
-
-  helper_->SkipListOfStrings();  // read positional parameter names.
-
-  if (!simple) {
-    helper_->SkipCanonicalNameReference();  // read typedef reference.
-  }
-
-  BuildTypeInternal();  // read return type.
-  if (result_.IsMalformed()) {
-    result_ = AbstractType::dynamic_type().raw();
-  }
-  signature_function.set_result_type(result_);
-
-  finalize_ = finalize;
-
-  Type& signature_type =
-      Type::ZoneHandle(Z, signature_function.SignatureType());
-
-  if (finalize_) {
-    signature_type ^=
-        ClassFinalizer::FinalizeType(*active_class_->klass, signature_type);
-    // Do not refer to signature_function anymore, since it may have been
-    // replaced during canonicalization.
-    signature_function = Function::null();
-  }
-
-  result_ = signature_type.raw();
-}
-
-void TypeTranslator::BuildTypeParameterType() {
-  intptr_t parameter_index = helper_->ReadUInt();  // read parameter index.
-  helper_->SkipOptionalDartType();                 // read bound.
-
-  const TypeArguments& class_types =
-      TypeArguments::Handle(Z, active_class_->klass->type_parameters());
-  if (parameter_index < class_types.Length()) {
-    // The index of the type parameter in [parameters] is
-    // the same index into the `klass->type_parameters()` array.
-    result_ ^= class_types.TypeAt(parameter_index);
-    return;
-  }
-  parameter_index -= class_types.Length();
-
-  if (active_class_->HasMember()) {
-    if (active_class_->MemberIsFactoryProcedure()) {
-      //
-      // WARNING: This is a little hackish:
-      //
-      // We have a static factory constructor. The kernel IR gives the factory
-      // constructor function its own type parameters (which are equal in name
-      // and number to the ones of the enclosing class). I.e.,
-      //
-      //   class A<T> {
-      //     factory A.x() { return new B<T>(); }
-      //   }
-      //
-      //  is basically translated to this:
-      //
-      //   class A<T> {
-      //     static A.x<T'>() { return new B<T'>(); }
-      //   }
-      //
-      if (class_types.Length() > parameter_index) {
-        result_ ^= class_types.TypeAt(parameter_index);
-        return;
-      }
-      parameter_index -= class_types.Length();
-    }
-
-    intptr_t procedure_type_parameter_count =
-        active_class_->MemberIsProcedure()
-            ? active_class_->MemberTypeParameterCount(Z)
-            : 0;
-    if (procedure_type_parameter_count > 0) {
-      if (procedure_type_parameter_count > parameter_index) {
-        if (I->reify_generic_functions()) {
-          result_ ^=
-              TypeArguments::Handle(Z, active_class_->member->type_parameters())
-                  .TypeAt(parameter_index);
-        } else {
-          result_ ^= Type::DynamicType();
-        }
-        return;
-      }
-      parameter_index -= procedure_type_parameter_count;
-    }
-  }
-
-  if (active_class_->local_type_parameters != NULL) {
-    if (parameter_index < active_class_->local_type_parameters->Length()) {
-      if (I->reify_generic_functions()) {
-        result_ ^=
-            active_class_->local_type_parameters->TypeAt(parameter_index);
-      } else {
-        result_ ^= Type::DynamicType();
-      }
-      return;
-    }
-    parameter_index -= active_class_->local_type_parameters->Length();
-  }
-
-  if (type_parameter_scope_ != NULL &&
-      parameter_index < type_parameter_scope_->outer_parameter_count() +
-                            type_parameter_scope_->parameter_count()) {
-    result_ ^= Type::DynamicType();
-    return;
-  }
-
-  H.ReportError(
-      helper_->script(), TokenPosition::kNoSource,
-      "Unbound type parameter found in %s.  Please report this at dartbug.com.",
-      active_class_->ToCString());
-}
-
-const TypeArguments& TypeTranslator::BuildTypeArguments(intptr_t length) {
-  bool only_dynamic = true;
-  intptr_t offset = helper_->ReaderOffset();
-  for (intptr_t i = 0; i < length; ++i) {
-    if (helper_->ReadTag() != kDynamicType) {  // Read the ith types tag.
-      only_dynamic = false;
-      helper_->SetOffset(offset);
-      break;
-    }
-  }
-  TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z);
-  if (!only_dynamic) {
-    type_arguments = TypeArguments::New(length);
-    for (intptr_t i = 0; i < length; ++i) {
-      BuildTypeInternal(true);  // read ith type.
-      type_arguments.SetTypeAt(i, result_);
-    }
-
-    if (finalize_) {
-      type_arguments = type_arguments.Canonicalize();
-    }
-  }
-  return type_arguments;
-}
-
-const TypeArguments& TypeTranslator::BuildInstantiatedTypeArguments(
-    const Class& receiver_class,
-    intptr_t length) {
-  const TypeArguments& type_arguments = BuildTypeArguments(length);
-
-  // If type_arguments is null all arguments are dynamic.
-  // If, however, this class doesn't specify all the type arguments directly we
-  // still need to finalize the type below in order to get any non-dynamic types
-  // from any super. See http://www.dartbug.com/29537.
-  if (type_arguments.IsNull() && receiver_class.NumTypeArguments() == length) {
-    return type_arguments;
-  }
-
-  // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
-  // finalize the argument types.
-  // (This can for example make the [type_arguments] vector larger)
-  Type& type = Type::Handle(
-      Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource));
-  if (finalize_) {
-    type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type);
-  }
-
-  const TypeArguments& instantiated_type_arguments =
-      TypeArguments::ZoneHandle(Z, type.arguments());
-  return instantiated_type_arguments;
-}
-
-void TypeTranslator::LoadAndSetupTypeParameters(
-    ActiveClass* active_class,
-    const Object& set_on,
-    intptr_t type_parameter_count,
-    const Function& parameterized_function) {
-  ASSERT(type_parameter_count >= 0);
-  if (type_parameter_count == 0) {
-    return;
-  }
-  ASSERT(set_on.IsClass() || set_on.IsFunction());
-  bool set_on_class = set_on.IsClass();
-  ASSERT(set_on_class == parameterized_function.IsNull());
-
-  // First setup the type parameters, so if any of the following code uses it
-  // (in a recursive way) we're fine.
-  TypeArguments& type_parameters = TypeArguments::Handle(Z);
-  TypeParameter& parameter = TypeParameter::Handle(Z);
-  const Type& null_bound = Type::Handle(Z);
-
-  // Step a) Create array of [TypeParameter] objects (without bound).
-  type_parameters = TypeArguments::New(type_parameter_count);
-  const Library& lib = Library::Handle(Z, active_class->klass->library());
-  {
-    AlternativeReadingScope alt(&helper_->reader_);
-    for (intptr_t i = 0; i < type_parameter_count; i++) {
-      TypeParameterHelper helper(helper_);
-      helper.Finish();
-      parameter = TypeParameter::New(
-          set_on_class ? *active_class->klass : Class::Handle(Z),
-          parameterized_function, i,
-          H.DartIdentifier(lib, helper.name_index_),  // read ith name index.
-          null_bound, TokenPosition::kNoSource);
-      type_parameters.SetTypeAt(i, parameter);
-    }
-  }
-
-  if (set_on.IsClass()) {
-    Class::Cast(set_on).set_type_parameters(type_parameters);
-  } else {
-    Function::Cast(set_on).set_type_parameters(type_parameters);
-  }
-
-  const Function* enclosing = NULL;
-  if (!parameterized_function.IsNull()) {
-    enclosing = &parameterized_function;
-  }
-  ActiveTypeParametersScope scope(active_class, enclosing, type_parameters, Z);
-
-  // Step b) Fill in the bounds of all [TypeParameter]s.
-  for (intptr_t i = 0; i < type_parameter_count; i++) {
-    TypeParameterHelper helper(helper_);
-    helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
-
-    // TODO(github.com/dart-lang/kernel/issues/42): This should be handled
-    // by the frontend.
-    parameter ^= type_parameters.TypeAt(i);
-    const Tag tag = helper_->PeekTag();  // peek ith bound type.
-    if (tag == kDynamicType) {
-      helper_->SkipDartType();  // read ith bound.
-      parameter.set_bound(Type::Handle(Z, I->object_store()->object_type()));
-    } else {
-      AbstractType& bound = BuildTypeWithoutFinalization();  // read ith bound.
-      if (bound.IsMalformedOrMalbounded()) {
-        bound = I->object_store()->object_type();
-      }
-      parameter.set_bound(bound);
-    }
-
-    helper.Finish();
-  }
-}
-
-const Type& TypeTranslator::ReceiverType(const Class& klass) {
-  ASSERT(!klass.IsNull());
-  ASSERT(!klass.IsTypedefClass());
-  // Note that if klass is _Closure, the returned type will be _Closure,
-  // and not the signature type.
-  Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
-  if (!type.IsNull()) {
-    return type;
-  }
-  type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
-                   klass.token_pos());
-  if (klass.is_type_finalized()) {
-    type ^= ClassFinalizer::FinalizeType(klass, type);
-    klass.SetCanonicalType(type);
-  }
-  return type;
-}
-
 StreamingConstantEvaluator::StreamingConstantEvaluator(
     StreamingFlowGraphBuilder* builder)
     : builder_(builder),
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 35f905c..82600d0 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -7,6 +7,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
+#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/kernel_to_il.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/kernel.h"
@@ -16,184 +17,6 @@
 namespace dart {
 namespace kernel {
 
-class TypeTranslator;
-
-struct DirectCallMetadata {
-  DirectCallMetadata(const Function& target, bool check_receiver_for_null)
-      : target_(target), check_receiver_for_null_(check_receiver_for_null) {}
-
-  const Function& target_;
-  const bool check_receiver_for_null_;
-};
-
-// Helper class which provides access to direct call metadata.
-class DirectCallMetadataHelper : public MetadataHelper {
- public:
-  static const char* tag() { return "vm.direct-call.metadata"; }
-
-  explicit DirectCallMetadataHelper(KernelReaderHelper* helper);
-
-  DirectCallMetadata GetDirectTargetForPropertyGet(intptr_t node_offset);
-  DirectCallMetadata GetDirectTargetForPropertySet(intptr_t node_offset);
-  DirectCallMetadata GetDirectTargetForMethodInvocation(intptr_t node_offset);
-
- private:
-  bool ReadMetadata(intptr_t node_offset,
-                    NameIndex* target_name,
-                    bool* check_receiver_for_null);
-};
-
-struct InferredTypeMetadata {
-  InferredTypeMetadata(intptr_t cid_, bool nullable_)
-      : cid(cid_), nullable(nullable_) {}
-
-  const intptr_t cid;
-  const bool nullable;
-
-  bool IsTrivial() const { return (cid == kDynamicCid) && nullable; }
-};
-
-// Helper class which provides access to inferred type metadata.
-class InferredTypeMetadataHelper : public MetadataHelper {
- public:
-  static const char* tag() { return "vm.inferred-type.metadata"; }
-
-  explicit InferredTypeMetadataHelper(KernelReaderHelper* helper);
-
-  InferredTypeMetadata GetInferredType(intptr_t node_offset);
-};
-
-struct ProcedureAttributesMetadata {
-  ProcedureAttributesMetadata(bool has_dynamic_invocations = true,
-                              bool has_non_this_uses = true,
-                              bool has_tearoff_uses = true)
-      : has_dynamic_invocations(has_dynamic_invocations),
-        has_non_this_uses(has_non_this_uses),
-        has_tearoff_uses(has_tearoff_uses) {}
-  bool has_dynamic_invocations;
-  bool has_non_this_uses;
-  bool has_tearoff_uses;
-};
-
-// Helper class which provides access to direct call metadata.
-class ProcedureAttributesMetadataHelper : public MetadataHelper {
- public:
-  static const char* tag() { return "vm.procedure-attributes.metadata"; }
-
-  explicit ProcedureAttributesMetadataHelper(KernelReaderHelper* helper);
-
-  ProcedureAttributesMetadata GetProcedureAttributes(intptr_t node_offset);
-
- private:
-  bool ReadMetadata(intptr_t node_offset,
-                    ProcedureAttributesMetadata* metadata);
-};
-
-#if defined(DART_USE_INTERPRETER)
-
-// Helper class which provides access to bytecode metadata.
-class BytecodeMetadataHelper : public MetadataHelper {
- public:
-  static const char* tag() { return "vm.bytecode"; }
-
-  explicit BytecodeMetadataHelper(KernelReaderHelper* helper,
-                                  TypeTranslator* type_translator,
-                                  ActiveClass* active_class);
-
-  void ReadMetadata(const Function& function);
-
- private:
-  // Returns the index of the last read pool entry.
-  intptr_t ReadPoolEntries(const Function& function,
-                           const Function& inner_function,
-                           const ObjectPool& pool,
-                           intptr_t from_index);
-  RawCode* ReadBytecode(const ObjectPool& pool);
-  void ReadExceptionsTable(const Code& bytecode);
-  RawTypedData* NativeEntry(const Function& function,
-                            const String& external_name);
-
-  TypeTranslator& type_translator_;
-  ActiveClass* const active_class_;
-};
-
-#endif  // defined(DART_USE_INTERPRETER)
-
-class TypeTranslator {
- public:
-  TypeTranslator(KernelReaderHelper* helper,
-                 ActiveClass* active_class,
-                 bool finalize = false);
-
-  // Can return a malformed type.
-  AbstractType& BuildType();
-  // Can return a malformed type.
-  AbstractType& BuildTypeWithoutFinalization();
-  // Is guaranteed to be not malformed.
-  AbstractType& BuildVariableType();
-
-  // Will return `TypeArguments::null()` in case any of the arguments are
-  // malformed.
-  const TypeArguments& BuildTypeArguments(intptr_t length);
-
-  // Will return `TypeArguments::null()` in case any of the arguments are
-  // malformed.
-  const TypeArguments& BuildInstantiatedTypeArguments(
-      const Class& receiver_class,
-      intptr_t length);
-
-  void LoadAndSetupTypeParameters(ActiveClass* active_class,
-                                  const Object& set_on,
-                                  intptr_t type_parameter_count,
-                                  const Function& parameterized_function);
-
-  const Type& ReceiverType(const Class& klass);
-
- private:
-  // Can build a malformed type.
-  void BuildTypeInternal(bool invalid_as_dynamic = false);
-  void BuildInterfaceType(bool simple);
-  void BuildFunctionType(bool simple);
-  void BuildTypeParameterType();
-
-  class TypeParameterScope {
-   public:
-    TypeParameterScope(TypeTranslator* translator, intptr_t parameter_count)
-        : parameter_count_(parameter_count),
-          outer_(translator->type_parameter_scope_),
-          translator_(translator) {
-      outer_parameter_count_ = 0;
-      if (outer_ != NULL) {
-        outer_parameter_count_ =
-            outer_->outer_parameter_count_ + outer_->parameter_count_;
-      }
-      translator_->type_parameter_scope_ = this;
-    }
-    ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
-
-    TypeParameterScope* outer() const { return outer_; }
-    intptr_t parameter_count() const { return parameter_count_; }
-    intptr_t outer_parameter_count() const { return outer_parameter_count_; }
-
-   private:
-    intptr_t parameter_count_;
-    intptr_t outer_parameter_count_;
-    TypeParameterScope* outer_;
-    TypeTranslator* translator_;
-  };
-
-  KernelReaderHelper* helper_;
-  TranslationHelper& translation_helper_;
-  ActiveClass* const active_class_;
-  TypeParameterScope* type_parameter_scope_;
-  Zone* zone_;
-  AbstractType& result_;
-  bool finalize_;
-
-  friend class StreamingScopeBuilder;
-  friend class KernelLoader;
-};
-
 class StreamingScopeBuilder {
  public:
   explicit StreamingScopeBuilder(ParsedFunction* parsed_function);
@@ -919,24 +742,6 @@
   friend class StreamingScopeBuilder;
 };
 
-class AlternativeScriptScope {
- public:
-  AlternativeScriptScope(TranslationHelper* helper,
-                         const Script& new_script,
-                         const Script& old_script)
-      : helper_(helper), old_script_(old_script) {
-    helper_->Reset();
-    helper_->InitFromScript(new_script);
-  }
-  ~AlternativeScriptScope() {
-    helper_->Reset();
-    helper_->InitFromScript(old_script_);
-  }
-
-  TranslationHelper* helper_;
-  const Script& old_script_;
-};
-
 // Helper class that reads a kernel Constant from binary.
 class ConstantHelper {
  public:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 38bfda8..83d8666 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -28,67 +28,6 @@
 #define T (type_translator_)
 #define I Isolate::Current()
 
-ActiveTypeParametersScope::ActiveTypeParametersScope(ActiveClass* active_class,
-                                                     const Function& innermost,
-                                                     Zone* Z)
-    : active_class_(active_class), saved_(*active_class) {
-  active_class_->enclosing = &innermost;
-
-  intptr_t num_params = 0;
-
-  Function& f = Function::Handle(Z);
-  TypeArguments& f_params = TypeArguments::Handle(Z);
-  for (f = innermost.raw(); f.parent_function() != Object::null();
-       f = f.parent_function()) {
-    f_params = f.type_parameters();
-    num_params += f_params.Length();
-  }
-  if (num_params == 0) return;
-
-  TypeArguments& params =
-      TypeArguments::Handle(Z, TypeArguments::New(num_params));
-
-  intptr_t index = num_params;
-  for (f = innermost.raw(); f.parent_function() != Object::null();
-       f = f.parent_function()) {
-    f_params = f.type_parameters();
-    for (intptr_t j = f_params.Length() - 1; j >= 0; --j) {
-      params.SetTypeAt(--index, AbstractType::Handle(Z, f_params.TypeAt(j)));
-    }
-  }
-
-  active_class_->local_type_parameters = &params;
-}
-
-ActiveTypeParametersScope::ActiveTypeParametersScope(
-    ActiveClass* active_class,
-    const Function* function,
-    const TypeArguments& new_params,
-    Zone* Z)
-    : active_class_(active_class), saved_(*active_class) {
-  active_class_->enclosing = function;
-
-  if (new_params.IsNull()) return;
-
-  const TypeArguments* old_params = active_class->local_type_parameters;
-  const intptr_t old_param_count =
-      old_params == NULL ? 0 : old_params->Length();
-  const TypeArguments& extended_params = TypeArguments::Handle(
-      Z, TypeArguments::New(old_param_count + new_params.Length()));
-
-  intptr_t index = 0;
-  for (intptr_t i = 0; i < old_param_count; ++i) {
-    extended_params.SetTypeAt(
-        index++, AbstractType::ZoneHandle(Z, old_params->TypeAt(i)));
-  }
-  for (intptr_t i = 0; i < new_params.Length(); ++i) {
-    extended_params.SetTypeAt(
-        index++, AbstractType::ZoneHandle(Z, new_params.TypeAt(i)));
-  }
-
-  active_class_->local_type_parameters = &extended_params;
-}
-
 Fragment& Fragment::operator+=(const Fragment& other) {
   if (entry == NULL) {
     entry = other.entry;
@@ -136,25 +75,6 @@
   return result;
 }
 
-intptr_t ActiveClass::MemberTypeParameterCount(Zone* zone) {
-  ASSERT(member != NULL);
-  if (member->IsFactory()) {
-    TypeArguments& class_types =
-        TypeArguments::Handle(zone, klass->type_parameters());
-    return class_types.Length();
-  } else if (member->IsMethodExtractor()) {
-    Function& extracted =
-        Function::Handle(zone, member->extracted_method_closure());
-    TypeArguments& function_types =
-        TypeArguments::Handle(zone, extracted.type_parameters());
-    return function_types.Length();
-  } else {
-    TypeArguments& function_types =
-        TypeArguments::Handle(zone, member->type_parameters());
-    return function_types.Length();
-  }
-}
-
 FlowGraphBuilder::FlowGraphBuilder(
     intptr_t kernel_offset,
     ParsedFunction* parsed_function,
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index a305b30..26defcf 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -201,110 +201,6 @@
 
 typedef ZoneGrowableArray<PushArgumentInstr*>* ArgumentArray;
 
-class ActiveClass {
- public:
-  ActiveClass()
-      : klass(NULL),
-        member(NULL),
-        enclosing(NULL),
-        local_type_parameters(NULL) {}
-
-  bool HasMember() { return member != NULL; }
-
-  bool MemberIsProcedure() {
-    ASSERT(member != NULL);
-    RawFunction::Kind function_kind = member->kind();
-    return function_kind == RawFunction::kRegularFunction ||
-           function_kind == RawFunction::kGetterFunction ||
-           function_kind == RawFunction::kSetterFunction ||
-           function_kind == RawFunction::kMethodExtractor ||
-           function_kind == RawFunction::kDynamicInvocationForwarder ||
-           member->IsFactory();
-  }
-
-  bool MemberIsFactoryProcedure() {
-    ASSERT(member != NULL);
-    return member->IsFactory();
-  }
-
-  intptr_t MemberTypeParameterCount(Zone* zone);
-
-  intptr_t ClassNumTypeArguments() {
-    ASSERT(klass != NULL);
-    return klass->NumTypeArguments();
-  }
-
-  const char* ToCString() {
-    return member != NULL ? member->ToCString() : klass->ToCString();
-  }
-
-  // The current enclosing class (or the library top-level class).
-  const Class* klass;
-
-  const Function* member;
-
-  // The innermost enclosing function. This is used for building types, as a
-  // parent for function types.
-  const Function* enclosing;
-
-  const TypeArguments* local_type_parameters;
-};
-
-class ActiveClassScope {
- public:
-  ActiveClassScope(ActiveClass* active_class, const Class* klass)
-      : active_class_(active_class), saved_(*active_class) {
-    active_class_->klass = klass;
-  }
-
-  ~ActiveClassScope() { *active_class_ = saved_; }
-
- private:
-  ActiveClass* active_class_;
-  ActiveClass saved_;
-};
-
-class ActiveMemberScope {
- public:
-  ActiveMemberScope(ActiveClass* active_class, const Function* member)
-      : active_class_(active_class), saved_(*active_class) {
-    // The class is inherited.
-    active_class_->member = member;
-  }
-
-  ~ActiveMemberScope() { *active_class_ = saved_; }
-
- private:
-  ActiveClass* active_class_;
-  ActiveClass saved_;
-};
-
-class ActiveTypeParametersScope {
- public:
-  // Set the local type parameters of the ActiveClass to be exactly all type
-  // parameters defined by 'innermost' and any enclosing *closures* (but not
-  // enclosing methods/top-level functions/classes).
-  //
-  // Also, the enclosing function is set to 'innermost'.
-  ActiveTypeParametersScope(ActiveClass* active_class,
-                            const Function& innermost,
-                            Zone* Z);
-
-  // Append the list of the local type parameters to the list in ActiveClass.
-  //
-  // Also, the enclosing function is set to 'function'.
-  ActiveTypeParametersScope(ActiveClass* active_class,
-                            const Function* function,
-                            const TypeArguments& new_params,
-                            Zone* Z);
-
-  ~ActiveTypeParametersScope() { *active_class_ = saved_; }
-
- private:
-  ActiveClass* active_class_;
-  ActiveClass saved_;
-};
-
 struct FunctionScope {
   intptr_t kernel_offset;
   LocalScope* scope;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 2c963ac..59b1acc 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -7,6 +7,7 @@
 #include "vm/class_finalizer.h"
 #include "vm/compiler/aot/precompiler.h"
 #include "vm/log.h"
+#include "vm/object_store.h"
 #include "vm/symbols.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1499,6 +1500,153 @@
   }
 }
 
+DirectCallMetadataHelper::DirectCallMetadataHelper(KernelReaderHelper* helper)
+    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
+
+bool DirectCallMetadataHelper::ReadMetadata(intptr_t node_offset,
+                                            NameIndex* target_name,
+                                            bool* check_receiver_for_null) {
+  intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+  if (md_offset < 0) {
+    return false;
+  }
+
+  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
+                              md_offset);
+
+  *target_name = helper_->ReadCanonicalNameReference();
+  *check_receiver_for_null = helper_->ReadBool();
+  return true;
+}
+
+DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForPropertyGet(
+    intptr_t node_offset) {
+  NameIndex kernel_name;
+  bool check_receiver_for_null = false;
+  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
+    return DirectCallMetadata(Function::null_function(), false);
+  }
+
+  if (H.IsProcedure(kernel_name) && !H.IsGetter(kernel_name)) {
+    // Tear-off. Use method extractor as direct call target.
+    const String& method_name = H.DartMethodName(kernel_name);
+    const Function& target_method = Function::ZoneHandle(
+        helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
+    const String& getter_name = H.DartGetterName(kernel_name);
+    return DirectCallMetadata(
+        Function::ZoneHandle(helper_->zone_,
+                             target_method.GetMethodExtractor(getter_name)),
+        check_receiver_for_null);
+  } else {
+    const String& getter_name = H.DartGetterName(kernel_name);
+    const Function& target = Function::ZoneHandle(
+        helper_->zone_, H.LookupMethodByMember(kernel_name, getter_name));
+    ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction());
+    return DirectCallMetadata(target, check_receiver_for_null);
+  }
+}
+
+DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForPropertySet(
+    intptr_t node_offset) {
+  NameIndex kernel_name;
+  bool check_receiver_for_null = false;
+  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
+    return DirectCallMetadata(Function::null_function(), false);
+  }
+
+  const String& method_name = H.DartSetterName(kernel_name);
+  const Function& target = Function::ZoneHandle(
+      helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
+  ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction());
+
+  return DirectCallMetadata(target, check_receiver_for_null);
+}
+
+DirectCallMetadata DirectCallMetadataHelper::GetDirectTargetForMethodInvocation(
+    intptr_t node_offset) {
+  NameIndex kernel_name;
+  bool check_receiver_for_null = false;
+  if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
+    return DirectCallMetadata(Function::null_function(), false);
+  }
+
+  const String& method_name = H.DartProcedureName(kernel_name);
+  const Function& target = Function::ZoneHandle(
+      helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
+
+  return DirectCallMetadata(target, check_receiver_for_null);
+}
+
+InferredTypeMetadataHelper::InferredTypeMetadataHelper(
+    KernelReaderHelper* helper)
+    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
+
+InferredTypeMetadata InferredTypeMetadataHelper::GetInferredType(
+    intptr_t node_offset) {
+  const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+  if (md_offset < 0) {
+    return InferredTypeMetadata(kDynamicCid, true);
+  }
+
+  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
+                              md_offset);
+
+  const NameIndex kernel_name = helper_->ReadCanonicalNameReference();
+  const bool nullable = helper_->ReadBool();
+
+  if (H.IsRoot(kernel_name)) {
+    return InferredTypeMetadata(kDynamicCid, nullable);
+  }
+
+  const Class& klass =
+      Class::Handle(helper_->zone_, H.LookupClassByKernelClass(kernel_name));
+  ASSERT(!klass.IsNull());
+
+  intptr_t cid = klass.id();
+  if (cid == kClosureCid) {
+    // VM uses more specific function types and doesn't expect instances of
+    // _Closure class, so inferred _Closure class doesn't make sense for the VM.
+    cid = kDynamicCid;
+  }
+
+  return InferredTypeMetadata(cid, nullable);
+}
+
+ProcedureAttributesMetadataHelper::ProcedureAttributesMetadataHelper(
+    KernelReaderHelper* helper)
+    : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
+
+bool ProcedureAttributesMetadataHelper::ReadMetadata(
+    intptr_t node_offset,
+    ProcedureAttributesMetadata* metadata) {
+  intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+  if (md_offset < 0) {
+    return false;
+  }
+
+  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
+                              md_offset);
+
+  const int kDynamicUsesBit = 1 << 0;
+  const int kNonThisUsesBit = 1 << 1;
+  const int kTearOffUsesBit = 1 << 2;
+
+  const uint8_t flags = helper_->ReadByte();
+  metadata->has_dynamic_invocations =
+      (flags & kDynamicUsesBit) == kDynamicUsesBit;
+  metadata->has_non_this_uses = (flags & kNonThisUsesBit) == kNonThisUsesBit;
+  metadata->has_tearoff_uses = (flags & kTearOffUsesBit) == kTearOffUsesBit;
+  return true;
+}
+
+ProcedureAttributesMetadata
+ProcedureAttributesMetadataHelper::GetProcedureAttributes(
+    intptr_t node_offset) {
+  ProcedureAttributesMetadata metadata;
+  ReadMetadata(node_offset, &metadata);
+  return metadata;
+}
+
 intptr_t KernelReaderHelper::ReaderOffset() const {
   return reader_.offset();
 }
@@ -2199,6 +2347,536 @@
   return position;
 }
 
+intptr_t ActiveClass::MemberTypeParameterCount(Zone* zone) {
+  ASSERT(member != NULL);
+  if (member->IsFactory()) {
+    TypeArguments& class_types =
+        TypeArguments::Handle(zone, klass->type_parameters());
+    return class_types.Length();
+  } else if (member->IsMethodExtractor()) {
+    Function& extracted =
+        Function::Handle(zone, member->extracted_method_closure());
+    TypeArguments& function_types =
+        TypeArguments::Handle(zone, extracted.type_parameters());
+    return function_types.Length();
+  } else {
+    TypeArguments& function_types =
+        TypeArguments::Handle(zone, member->type_parameters());
+    return function_types.Length();
+  }
+}
+
+ActiveTypeParametersScope::ActiveTypeParametersScope(ActiveClass* active_class,
+                                                     const Function& innermost,
+                                                     Zone* Z)
+    : active_class_(active_class), saved_(*active_class) {
+  active_class_->enclosing = &innermost;
+
+  intptr_t num_params = 0;
+
+  Function& f = Function::Handle(Z);
+  TypeArguments& f_params = TypeArguments::Handle(Z);
+  for (f = innermost.raw(); f.parent_function() != Object::null();
+       f = f.parent_function()) {
+    f_params = f.type_parameters();
+    num_params += f_params.Length();
+  }
+  if (num_params == 0) return;
+
+  TypeArguments& params =
+      TypeArguments::Handle(Z, TypeArguments::New(num_params));
+
+  intptr_t index = num_params;
+  for (f = innermost.raw(); f.parent_function() != Object::null();
+       f = f.parent_function()) {
+    f_params = f.type_parameters();
+    for (intptr_t j = f_params.Length() - 1; j >= 0; --j) {
+      params.SetTypeAt(--index, AbstractType::Handle(Z, f_params.TypeAt(j)));
+    }
+  }
+
+  active_class_->local_type_parameters = &params;
+}
+
+ActiveTypeParametersScope::ActiveTypeParametersScope(
+    ActiveClass* active_class,
+    const Function* function,
+    const TypeArguments& new_params,
+    Zone* Z)
+    : active_class_(active_class), saved_(*active_class) {
+  active_class_->enclosing = function;
+
+  if (new_params.IsNull()) return;
+
+  const TypeArguments* old_params = active_class->local_type_parameters;
+  const intptr_t old_param_count =
+      old_params == NULL ? 0 : old_params->Length();
+  const TypeArguments& extended_params = TypeArguments::Handle(
+      Z, TypeArguments::New(old_param_count + new_params.Length()));
+
+  intptr_t index = 0;
+  for (intptr_t i = 0; i < old_param_count; ++i) {
+    extended_params.SetTypeAt(
+        index++, AbstractType::ZoneHandle(Z, old_params->TypeAt(i)));
+  }
+  for (intptr_t i = 0; i < new_params.Length(); ++i) {
+    extended_params.SetTypeAt(
+        index++, AbstractType::ZoneHandle(Z, new_params.TypeAt(i)));
+  }
+
+  active_class_->local_type_parameters = &extended_params;
+}
+
+TypeTranslator::TypeTranslator(KernelReaderHelper* helper,
+                               ActiveClass* active_class,
+                               bool finalize)
+    : helper_(helper),
+      translation_helper_(helper->translation_helper_),
+      active_class_(active_class),
+      type_parameter_scope_(NULL),
+      zone_(translation_helper_.zone()),
+      result_(AbstractType::Handle(translation_helper_.zone())),
+      finalize_(finalize) {}
+
+AbstractType& TypeTranslator::BuildType() {
+  BuildTypeInternal();
+
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return AbstractType::ZoneHandle(Z, result_.raw());
+}
+
+AbstractType& TypeTranslator::BuildTypeWithoutFinalization() {
+  bool saved_finalize = finalize_;
+  finalize_ = false;
+  BuildTypeInternal();
+  finalize_ = saved_finalize;
+
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return AbstractType::ZoneHandle(Z, result_.raw());
+}
+
+AbstractType& TypeTranslator::BuildVariableType() {
+  AbstractType& abstract_type = BuildType();
+
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  AbstractType& type = Type::ZoneHandle(Z);
+
+  if (abstract_type.IsMalformed()) {
+    type = AbstractType::dynamic_type().raw();
+  } else {
+    type = result_.raw();
+  }
+
+  return type;
+}
+
+void TypeTranslator::BuildTypeInternal(bool invalid_as_dynamic) {
+  Tag tag = helper_->ReadTag();
+  switch (tag) {
+    case kInvalidType:
+      if (invalid_as_dynamic) {
+        result_ = Object::dynamic_type().raw();
+      } else {
+        result_ = ClassFinalizer::NewFinalizedMalformedType(
+            Error::Handle(Z),  // No previous error.
+            Script::Handle(Z, Script::null()), TokenPosition::kNoSource,
+            "[InvalidType] in Kernel IR.");
+      }
+      break;
+    case kDynamicType:
+      result_ = Object::dynamic_type().raw();
+      break;
+    case kVoidType:
+      result_ = Object::void_type().raw();
+      break;
+    case kBottomType:
+      result_ =
+          Class::Handle(Z, I->object_store()->null_class()).CanonicalType();
+      break;
+    case kInterfaceType:
+      BuildInterfaceType(false);
+      break;
+    case kSimpleInterfaceType:
+      BuildInterfaceType(true);
+      break;
+    case kFunctionType:
+      BuildFunctionType(false);
+      break;
+    case kSimpleFunctionType:
+      BuildFunctionType(true);
+      break;
+    case kTypeParameterType:
+      BuildTypeParameterType();
+      break;
+    default:
+      helper_->ReportUnexpectedTag("type", tag);
+      UNREACHABLE();
+  }
+}
+
+void TypeTranslator::BuildInterfaceType(bool simple) {
+  // NOTE: That an interface type like `T<A, B>` is considered to be
+  // malformed iff `T` is malformed.
+  //   => We therefore ignore errors in `A` or `B`.
+
+  NameIndex klass_name =
+      helper_->ReadCanonicalNameReference();  // read klass_name.
+
+  intptr_t length;
+  if (simple) {
+    length = 0;
+  } else {
+    length = helper_->ReadListLength();  // read type_arguments list length.
+  }
+  const TypeArguments& type_arguments =
+      BuildTypeArguments(length);  // read type arguments.
+
+  Object& klass = Object::Handle(Z, H.LookupClassByKernelClass(klass_name));
+  result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource);
+  if (finalize_) {
+    ASSERT(active_class_->klass != NULL);
+    result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_);
+  }
+}
+
+void TypeTranslator::BuildFunctionType(bool simple) {
+  Function& signature_function = Function::ZoneHandle(
+      Z, Function::NewSignatureFunction(*active_class_->klass,
+                                        active_class_->enclosing != NULL
+                                            ? *active_class_->enclosing
+                                            : Function::Handle(Z),
+                                        TokenPosition::kNoSource));
+
+  // Suspend finalization of types inside this one. They will be finalized after
+  // the whole function type is constructed.
+  //
+  // TODO(31213): Test further when nested generic function types
+  // are supported by fasta.
+  bool finalize = finalize_;
+  finalize_ = false;
+
+  if (!simple) {
+    LoadAndSetupTypeParameters(active_class_, signature_function,
+                               helper_->ReadListLength(), signature_function);
+  }
+
+  ActiveTypeParametersScope scope(
+      active_class_, &signature_function,
+      TypeArguments::Handle(Z, signature_function.type_parameters()), Z);
+
+  intptr_t required_count;
+  intptr_t all_count;
+  intptr_t positional_count;
+  if (!simple) {
+    required_count = helper_->ReadUInt();  // read required parameter count.
+    all_count = helper_->ReadUInt();       // read total parameter count.
+    positional_count =
+        helper_->ReadListLength();  // read positional_parameters list length.
+  } else {
+    positional_count =
+        helper_->ReadListLength();  // read positional_parameters list length.
+    required_count = positional_count;
+    all_count = positional_count;
+  }
+
+  const Array& parameter_types =
+      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+  signature_function.set_parameter_types(parameter_types);
+  const Array& parameter_names =
+      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+  signature_function.set_parameter_names(parameter_names);
+
+  intptr_t pos = 0;
+  parameter_types.SetAt(pos, AbstractType::dynamic_type());
+  parameter_names.SetAt(pos, H.DartSymbolPlain("_receiver_"));
+  ++pos;
+  for (intptr_t i = 0; i < positional_count; ++i, ++pos) {
+    BuildTypeInternal();  // read ith positional parameter.
+    if (result_.IsMalformed()) {
+      result_ = AbstractType::dynamic_type().raw();
+    }
+    parameter_types.SetAt(pos, result_);
+    parameter_names.SetAt(pos, H.DartSymbolPlain("noname"));
+  }
+
+  // The additional first parameter is the receiver type (set to dynamic).
+  signature_function.set_num_fixed_parameters(1 + required_count);
+  signature_function.SetNumOptionalParameters(
+      all_count - required_count, positional_count > required_count);
+
+  if (!simple) {
+    const intptr_t named_count =
+        helper_->ReadListLength();  // read named_parameters list length.
+    for (intptr_t i = 0; i < named_count; ++i, ++pos) {
+      // read string reference (i.e. named_parameters[i].name).
+      String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
+      BuildTypeInternal();  // read named_parameters[i].type.
+      if (result_.IsMalformed()) {
+        result_ = AbstractType::dynamic_type().raw();
+      }
+      parameter_types.SetAt(pos, result_);
+      parameter_names.SetAt(pos, name);
+    }
+  }
+
+  helper_->SkipListOfStrings();  // read positional parameter names.
+
+  if (!simple) {
+    helper_->SkipCanonicalNameReference();  // read typedef reference.
+  }
+
+  BuildTypeInternal();  // read return type.
+  if (result_.IsMalformed()) {
+    result_ = AbstractType::dynamic_type().raw();
+  }
+  signature_function.set_result_type(result_);
+
+  finalize_ = finalize;
+
+  Type& signature_type =
+      Type::ZoneHandle(Z, signature_function.SignatureType());
+
+  if (finalize_) {
+    signature_type ^=
+        ClassFinalizer::FinalizeType(*active_class_->klass, signature_type);
+    // Do not refer to signature_function anymore, since it may have been
+    // replaced during canonicalization.
+    signature_function = Function::null();
+  }
+
+  result_ = signature_type.raw();
+}
+
+void TypeTranslator::BuildTypeParameterType() {
+  intptr_t parameter_index = helper_->ReadUInt();  // read parameter index.
+  helper_->SkipOptionalDartType();                 // read bound.
+
+  const TypeArguments& class_types =
+      TypeArguments::Handle(Z, active_class_->klass->type_parameters());
+  if (parameter_index < class_types.Length()) {
+    // The index of the type parameter in [parameters] is
+    // the same index into the `klass->type_parameters()` array.
+    result_ ^= class_types.TypeAt(parameter_index);
+    return;
+  }
+  parameter_index -= class_types.Length();
+
+  if (active_class_->HasMember()) {
+    if (active_class_->MemberIsFactoryProcedure()) {
+      //
+      // WARNING: This is a little hackish:
+      //
+      // We have a static factory constructor. The kernel IR gives the factory
+      // constructor function its own type parameters (which are equal in name
+      // and number to the ones of the enclosing class). I.e.,
+      //
+      //   class A<T> {
+      //     factory A.x() { return new B<T>(); }
+      //   }
+      //
+      //  is basically translated to this:
+      //
+      //   class A<T> {
+      //     static A.x<T'>() { return new B<T'>(); }
+      //   }
+      //
+      if (class_types.Length() > parameter_index) {
+        result_ ^= class_types.TypeAt(parameter_index);
+        return;
+      }
+      parameter_index -= class_types.Length();
+    }
+
+    intptr_t procedure_type_parameter_count =
+        active_class_->MemberIsProcedure()
+            ? active_class_->MemberTypeParameterCount(Z)
+            : 0;
+    if (procedure_type_parameter_count > 0) {
+      if (procedure_type_parameter_count > parameter_index) {
+        if (I->reify_generic_functions()) {
+          result_ ^=
+              TypeArguments::Handle(Z, active_class_->member->type_parameters())
+                  .TypeAt(parameter_index);
+        } else {
+          result_ ^= Type::DynamicType();
+        }
+        return;
+      }
+      parameter_index -= procedure_type_parameter_count;
+    }
+  }
+
+  if (active_class_->local_type_parameters != NULL) {
+    if (parameter_index < active_class_->local_type_parameters->Length()) {
+      if (I->reify_generic_functions()) {
+        result_ ^=
+            active_class_->local_type_parameters->TypeAt(parameter_index);
+      } else {
+        result_ ^= Type::DynamicType();
+      }
+      return;
+    }
+    parameter_index -= active_class_->local_type_parameters->Length();
+  }
+
+  if (type_parameter_scope_ != NULL &&
+      parameter_index < type_parameter_scope_->outer_parameter_count() +
+                            type_parameter_scope_->parameter_count()) {
+    result_ ^= Type::DynamicType();
+    return;
+  }
+
+  H.ReportError(
+      helper_->script(), TokenPosition::kNoSource,
+      "Unbound type parameter found in %s.  Please report this at dartbug.com.",
+      active_class_->ToCString());
+}
+
+const TypeArguments& TypeTranslator::BuildTypeArguments(intptr_t length) {
+  bool only_dynamic = true;
+  intptr_t offset = helper_->ReaderOffset();
+  for (intptr_t i = 0; i < length; ++i) {
+    if (helper_->ReadTag() != kDynamicType) {  // Read the ith types tag.
+      only_dynamic = false;
+      helper_->SetOffset(offset);
+      break;
+    }
+  }
+  TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z);
+  if (!only_dynamic) {
+    type_arguments = TypeArguments::New(length);
+    for (intptr_t i = 0; i < length; ++i) {
+      BuildTypeInternal(true);  // read ith type.
+      type_arguments.SetTypeAt(i, result_);
+    }
+
+    if (finalize_) {
+      type_arguments = type_arguments.Canonicalize();
+    }
+  }
+  return type_arguments;
+}
+
+const TypeArguments& TypeTranslator::BuildInstantiatedTypeArguments(
+    const Class& receiver_class,
+    intptr_t length) {
+  const TypeArguments& type_arguments = BuildTypeArguments(length);
+
+  // If type_arguments is null all arguments are dynamic.
+  // If, however, this class doesn't specify all the type arguments directly we
+  // still need to finalize the type below in order to get any non-dynamic types
+  // from any super. See http://www.dartbug.com/29537.
+  if (type_arguments.IsNull() && receiver_class.NumTypeArguments() == length) {
+    return type_arguments;
+  }
+
+  // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
+  // finalize the argument types.
+  // (This can for example make the [type_arguments] vector larger)
+  Type& type = Type::Handle(
+      Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource));
+  if (finalize_) {
+    type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type);
+  }
+
+  const TypeArguments& instantiated_type_arguments =
+      TypeArguments::ZoneHandle(Z, type.arguments());
+  return instantiated_type_arguments;
+}
+
+void TypeTranslator::LoadAndSetupTypeParameters(
+    ActiveClass* active_class,
+    const Object& set_on,
+    intptr_t type_parameter_count,
+    const Function& parameterized_function) {
+  ASSERT(type_parameter_count >= 0);
+  if (type_parameter_count == 0) {
+    return;
+  }
+  ASSERT(set_on.IsClass() || set_on.IsFunction());
+  bool set_on_class = set_on.IsClass();
+  ASSERT(set_on_class == parameterized_function.IsNull());
+
+  // First setup the type parameters, so if any of the following code uses it
+  // (in a recursive way) we're fine.
+  TypeArguments& type_parameters = TypeArguments::Handle(Z);
+  TypeParameter& parameter = TypeParameter::Handle(Z);
+  const Type& null_bound = Type::Handle(Z);
+
+  // Step a) Create array of [TypeParameter] objects (without bound).
+  type_parameters = TypeArguments::New(type_parameter_count);
+  const Library& lib = Library::Handle(Z, active_class->klass->library());
+  {
+    AlternativeReadingScope alt(&helper_->reader_);
+    for (intptr_t i = 0; i < type_parameter_count; i++) {
+      TypeParameterHelper helper(helper_);
+      helper.Finish();
+      parameter = TypeParameter::New(
+          set_on_class ? *active_class->klass : Class::Handle(Z),
+          parameterized_function, i,
+          H.DartIdentifier(lib, helper.name_index_),  // read ith name index.
+          null_bound, TokenPosition::kNoSource);
+      type_parameters.SetTypeAt(i, parameter);
+    }
+  }
+
+  if (set_on.IsClass()) {
+    Class::Cast(set_on).set_type_parameters(type_parameters);
+  } else {
+    Function::Cast(set_on).set_type_parameters(type_parameters);
+  }
+
+  const Function* enclosing = NULL;
+  if (!parameterized_function.IsNull()) {
+    enclosing = &parameterized_function;
+  }
+  ActiveTypeParametersScope scope(active_class, enclosing, type_parameters, Z);
+
+  // Step b) Fill in the bounds of all [TypeParameter]s.
+  for (intptr_t i = 0; i < type_parameter_count; i++) {
+    TypeParameterHelper helper(helper_);
+    helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
+
+    // TODO(github.com/dart-lang/kernel/issues/42): This should be handled
+    // by the frontend.
+    parameter ^= type_parameters.TypeAt(i);
+    const Tag tag = helper_->PeekTag();  // peek ith bound type.
+    if (tag == kDynamicType) {
+      helper_->SkipDartType();  // read ith bound.
+      parameter.set_bound(Type::Handle(Z, I->object_store()->object_type()));
+    } else {
+      AbstractType& bound = BuildTypeWithoutFinalization();  // read ith bound.
+      if (bound.IsMalformedOrMalbounded()) {
+        bound = I->object_store()->object_type();
+      }
+      parameter.set_bound(bound);
+    }
+
+    helper.Finish();
+  }
+}
+
+const Type& TypeTranslator::ReceiverType(const Class& klass) {
+  ASSERT(!klass.IsNull());
+  ASSERT(!klass.IsTypedefClass());
+  // Note that if klass is _Closure, the returned type will be _Closure,
+  // and not the signature type.
+  Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
+  if (!type.IsNull()) {
+    return type;
+  }
+  type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
+                   klass.token_pos());
+  if (klass.is_type_finalized()) {
+    type ^= ClassFinalizer::FinalizeType(klass, type);
+    klass.SetCanonicalType(type);
+  }
+  return type;
+}
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 75d4566..6964154 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -778,6 +778,77 @@
   intptr_t last_mapping_index_;
 };
 
+struct DirectCallMetadata {
+  DirectCallMetadata(const Function& target, bool check_receiver_for_null)
+      : target_(target), check_receiver_for_null_(check_receiver_for_null) {}
+
+  const Function& target_;
+  const bool check_receiver_for_null_;
+};
+
+// Helper class which provides access to direct call metadata.
+class DirectCallMetadataHelper : public MetadataHelper {
+ public:
+  static const char* tag() { return "vm.direct-call.metadata"; }
+
+  explicit DirectCallMetadataHelper(KernelReaderHelper* helper);
+
+  DirectCallMetadata GetDirectTargetForPropertyGet(intptr_t node_offset);
+  DirectCallMetadata GetDirectTargetForPropertySet(intptr_t node_offset);
+  DirectCallMetadata GetDirectTargetForMethodInvocation(intptr_t node_offset);
+
+ private:
+  bool ReadMetadata(intptr_t node_offset,
+                    NameIndex* target_name,
+                    bool* check_receiver_for_null);
+};
+
+struct InferredTypeMetadata {
+  InferredTypeMetadata(intptr_t cid_, bool nullable_)
+      : cid(cid_), nullable(nullable_) {}
+
+  const intptr_t cid;
+  const bool nullable;
+
+  bool IsTrivial() const { return (cid == kDynamicCid) && nullable; }
+};
+
+// Helper class which provides access to inferred type metadata.
+class InferredTypeMetadataHelper : public MetadataHelper {
+ public:
+  static const char* tag() { return "vm.inferred-type.metadata"; }
+
+  explicit InferredTypeMetadataHelper(KernelReaderHelper* helper);
+
+  InferredTypeMetadata GetInferredType(intptr_t node_offset);
+};
+
+struct ProcedureAttributesMetadata {
+  ProcedureAttributesMetadata(bool has_dynamic_invocations = true,
+                              bool has_non_this_uses = true,
+                              bool has_tearoff_uses = true)
+      : has_dynamic_invocations(has_dynamic_invocations),
+        has_non_this_uses(has_non_this_uses),
+        has_tearoff_uses(has_tearoff_uses) {}
+  bool has_dynamic_invocations;
+  bool has_non_this_uses;
+  bool has_tearoff_uses;
+};
+
+// Helper class which provides access to direct call metadata.
+class ProcedureAttributesMetadataHelper : public MetadataHelper {
+ public:
+  static const char* tag() { return "vm.procedure-attributes.metadata"; }
+
+  explicit ProcedureAttributesMetadataHelper(KernelReaderHelper* helper);
+
+  ProcedureAttributesMetadata GetProcedureAttributes(intptr_t node_offset);
+
+ private:
+  bool ReadMetadata(intptr_t node_offset,
+                    ProcedureAttributesMetadata* metadata);
+};
+
 class KernelReaderHelper {
  public:
   KernelReaderHelper(Zone* zone,
@@ -910,6 +981,185 @@
 #endif  // defined(DART_USE_INTERPRETER)
 };
 
+class ActiveClass {
+ public:
+  ActiveClass()
+      : klass(NULL),
+        member(NULL),
+        enclosing(NULL),
+        local_type_parameters(NULL) {}
+
+  bool HasMember() { return member != NULL; }
+
+  bool MemberIsProcedure() {
+    ASSERT(member != NULL);
+    RawFunction::Kind function_kind = member->kind();
+    return function_kind == RawFunction::kRegularFunction ||
+           function_kind == RawFunction::kGetterFunction ||
+           function_kind == RawFunction::kSetterFunction ||
+           function_kind == RawFunction::kMethodExtractor ||
+           function_kind == RawFunction::kDynamicInvocationForwarder ||
+           member->IsFactory();
+  }
+
+  bool MemberIsFactoryProcedure() {
+    ASSERT(member != NULL);
+    return member->IsFactory();
+  }
+
+  intptr_t MemberTypeParameterCount(Zone* zone);
+
+  intptr_t ClassNumTypeArguments() {
+    ASSERT(klass != NULL);
+    return klass->NumTypeArguments();
+  }
+
+  const char* ToCString() {
+    return member != NULL ? member->ToCString() : klass->ToCString();
+  }
+
+  // The current enclosing class (or the library top-level class).
+  const Class* klass;
+
+  const Function* member;
+
+  // The innermost enclosing function. This is used for building types, as a
+  // parent for function types.
+  const Function* enclosing;
+
+  const TypeArguments* local_type_parameters;
+};
+
+class ActiveClassScope {
+ public:
+  ActiveClassScope(ActiveClass* active_class, const Class* klass)
+      : active_class_(active_class), saved_(*active_class) {
+    active_class_->klass = klass;
+  }
+
+  ~ActiveClassScope() { *active_class_ = saved_; }
+
+ private:
+  ActiveClass* active_class_;
+  ActiveClass saved_;
+};
+
+class ActiveMemberScope {
+ public:
+  ActiveMemberScope(ActiveClass* active_class, const Function* member)
+      : active_class_(active_class), saved_(*active_class) {
+    // The class is inherited.
+    active_class_->member = member;
+  }
+
+  ~ActiveMemberScope() { *active_class_ = saved_; }
+
+ private:
+  ActiveClass* active_class_;
+  ActiveClass saved_;
+};
+
+class ActiveTypeParametersScope {
+ public:
+  // Set the local type parameters of the ActiveClass to be exactly all type
+  // parameters defined by 'innermost' and any enclosing *closures* (but not
+  // enclosing methods/top-level functions/classes).
+  //
+  // Also, the enclosing function is set to 'innermost'.
+  ActiveTypeParametersScope(ActiveClass* active_class,
+                            const Function& innermost,
+                            Zone* Z);
+
+  // Append the list of the local type parameters to the list in ActiveClass.
+  //
+  // Also, the enclosing function is set to 'function'.
+  ActiveTypeParametersScope(ActiveClass* active_class,
+                            const Function* function,
+                            const TypeArguments& new_params,
+                            Zone* Z);
+
+  ~ActiveTypeParametersScope() { *active_class_ = saved_; }
+
+ private:
+  ActiveClass* active_class_;
+  ActiveClass saved_;
+};
+
+class TypeTranslator {
+ public:
+  TypeTranslator(KernelReaderHelper* helper,
+                 ActiveClass* active_class,
+                 bool finalize = false);
+
+  // Can return a malformed type.
+  AbstractType& BuildType();
+  // Can return a malformed type.
+  AbstractType& BuildTypeWithoutFinalization();
+  // Is guaranteed to be not malformed.
+  AbstractType& BuildVariableType();
+
+  // Will return `TypeArguments::null()` in case any of the arguments are
+  // malformed.
+  const TypeArguments& BuildTypeArguments(intptr_t length);
+
+  // Will return `TypeArguments::null()` in case any of the arguments are
+  // malformed.
+  const TypeArguments& BuildInstantiatedTypeArguments(
+      const Class& receiver_class,
+      intptr_t length);
+
+  void LoadAndSetupTypeParameters(ActiveClass* active_class,
+                                  const Object& set_on,
+                                  intptr_t type_parameter_count,
+                                  const Function& parameterized_function);
+
+  const Type& ReceiverType(const Class& klass);
+
+ private:
+  // Can build a malformed type.
+  void BuildTypeInternal(bool invalid_as_dynamic = false);
+  void BuildInterfaceType(bool simple);
+  void BuildFunctionType(bool simple);
+  void BuildTypeParameterType();
+
+  class TypeParameterScope {
+   public:
+    TypeParameterScope(TypeTranslator* translator, intptr_t parameter_count)
+        : parameter_count_(parameter_count),
+          outer_(translator->type_parameter_scope_),
+          translator_(translator) {
+      outer_parameter_count_ = 0;
+      if (outer_ != NULL) {
+        outer_parameter_count_ =
+            outer_->outer_parameter_count_ + outer_->parameter_count_;
+      }
+      translator_->type_parameter_scope_ = this;
+    }
+    ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
+
+    TypeParameterScope* outer() const { return outer_; }
+    intptr_t parameter_count() const { return parameter_count_; }
+    intptr_t outer_parameter_count() const { return outer_parameter_count_; }
+
+   private:
+    intptr_t parameter_count_;
+    intptr_t outer_parameter_count_;
+    TypeParameterScope* outer_;
+    TypeTranslator* translator_;
+  };
+
+  KernelReaderHelper* helper_;
+  TranslationHelper& translation_helper_;
+  ActiveClass* const active_class_;
+  TypeParameterScope* type_parameter_scope_;
+  Zone* zone_;
+  AbstractType& result_;
+  bool finalize_;
+
+  friend class StreamingScopeBuilder;
+  friend class KernelLoader;
+};
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2440091..65fd953 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -13540,7 +13540,7 @@
 }
 
 #if defined(TAG_IC_DATA)
-void ICData::set_tag(intptr_t value) const {
+void ICData::set_tag(Tag value) const {
   StoreNonPointer(&raw_ptr()->tag_, value);
 }
 #endif
@@ -14427,7 +14427,7 @@
   NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id));
   result.set_state_bits(0);
 #if defined(TAG_IC_DATA)
-  result.set_tag(-1);
+  result.set_tag(ICData::Tag::kUnknown);
 #endif
   result.set_rebind_rule(rebind_rule);
   result.SetNumArgsTested(num_args_tested);
@@ -14451,7 +14451,7 @@
   result.set_deopt_id(Thread::kNoDeoptId);
   result.set_state_bits(0);
 #if defined(TAG_IC_DATA)
-  result.set_tag(-1);
+  result.set_tag(ICData::Tag::kUnknown);
 #endif
   return result.raw();
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index ba4f605..17cc0f4 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2004,8 +2004,9 @@
   enum { kCachedICDataArrayCount = 4 };
 
 #if defined(TAG_IC_DATA)
-  void set_tag(intptr_t value) const;
-  intptr_t tag() const { return raw_ptr()->tag_; }
+  using Tag = RawICData::Tag;
+  void set_tag(Tag value) const;
+  Tag tag() const { return raw_ptr()->tag_; }
 #endif
 
   bool is_static_call() const;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 5d7a7f0..88bd409 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1663,8 +1663,10 @@
   NOT_IN_PRECOMPILED(int32_t deopt_id_);
   uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons.
 #if defined(TAG_IC_DATA)
-  intptr_t tag_;  // Debugging, verifying that the icdata is assigned to the
-                  // same instruction again. Store -1 or Instruction::Tag.
+  enum class Tag : intptr_t{kUnknown, kInstanceCall, kStaticCall};
+
+  Tag tag_;  // Debugging, verifying that the icdata is assigned to the
+             // same instruction again.
 #endif
 };
 
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 435e697..2609707 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1639,7 +1639,7 @@
   NOT_IN_PRECOMPILED(result.set_deopt_id(reader->Read<int32_t>()));
   result.set_state_bits(reader->Read<uint32_t>());
 #if defined(TAG_IC_DATA)
-  result.set_tag(reader->Read<int16_t>());
+  result.set_tag(static_cast<ICData::Tag>(reader->Read<int16_t>()));
 #endif
 
   // Set all the object fields.
@@ -1666,7 +1666,7 @@
   NOT_IN_PRECOMPILED(writer->Write<int32_t>(ptr()->deopt_id_));
   writer->Write<uint32_t>(ptr()->state_bits_);
 #if defined(TAG_IC_DATA)
-  writer->Write<int16_t>(ptr()->tag_);
+  writer->Write<int16_t>(static_cast<int64_t>(ptr()->tag_));
 #endif
 
   // Write out all the object pointer fields.
