diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 688f192..42e1d22 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1197,14 +1197,7 @@
       kernel::BytecodeReader::LoadClassDeclaration(cls);
     }
 #endif
-    // TODO(36584) : We expect is_type_finalized to be true for all classes
-    // here, but with eager reading of the constant table we get into
-    // situations where we see classes whose types have not been finalized yet,
-    // the real solution is to implement lazy evaluation of constants. This is
-    // a temporary workaround until lazy evaluation is implemented.
-    if (!cls.is_type_finalized()) {
-      FinalizeTypesInClass(cls);
-    }
+    ASSERT(cls.is_type_finalized());
     ClassFinalizer::FinalizeClass(cls);
     return Error::null();
   } else {
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index a69ee37..e5065e2 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -168,10 +168,12 @@
         EvaluateNullLiteral();
         break;
       case kConstantExpression:
-        EvaluateConstantExpression(tag);
+        helper_->ReadPosition();
+        helper_->SkipDartType();
+        result_ = EvaluateConstantExpression(helper_->ReadUInt());
         break;
       case kDeprecated_ConstantExpression:
-        EvaluateConstantExpression(tag);
+        result_ = EvaluateConstantExpression(helper_->ReadUInt());
         break;
       default:
         H.ReportError(
@@ -291,6 +293,248 @@
   return metadata_values.raw();
 }
 
+RawInstance* ConstantEvaluator::EvaluateConstantExpression(
+    intptr_t constant_offset) {
+  ASSERT(!H.constants().IsNull());
+  ASSERT(!H.constants_table().IsNull());  // raw bytes
+
+  // For kernel-level cache (in contrast with script-level caching),
+  // we need to access the raw constants array inside the shared
+  // KernelProgramInfo directly, so that all scripts will see the
+  // results after new insertions. These accesses at kernel-level
+  // must be locked since mutator and background compiler can
+  // access the array at the same time.
+  {
+    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    KernelConstantsMap constant_map(H.info().constants());
+    result_ ^= constant_map.GetOrNull(constant_offset);
+    ASSERT(constant_map.Release().raw() == H.info().constants());
+  }
+
+  // On miss, evaluate, and insert value.
+  if (result_.IsNull()) {
+    result_ = EvaluateConstant(constant_offset);
+    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    KernelConstantsMap constant_map(H.info().constants());
+    auto insert = constant_map.InsertNewOrGetValue(constant_offset, result_);
+    ASSERT(insert == result_.raw());
+    H.info().set_constants(constant_map.Release());  // update!
+  }
+  return result_.raw();
+}
+
+RawInstance* ConstantEvaluator::EvaluateConstant(intptr_t constant_offset) {
+  // Get reader directly into raw bytes of constant table.
+  KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
+  reader.ReadUInt();  // skip variable-sized int for adjusted constant offset
+  reader.SetOffset(reader.ReaderOffset() + constant_offset);
+  // Construct constant from raw bytes.
+  Instance& instance = Instance::Handle(Z);
+  const intptr_t constant_tag = reader.ReadByte();
+  switch (constant_tag) {
+    case kNullConstant:
+      instance = Instance::null();
+      break;
+    case kBoolConstant:
+      instance = reader.ReadByte() == 1 ? Object::bool_true().raw()
+                                        : Object::bool_false().raw();
+      break;
+    case kIntConstant: {
+      uint8_t payload = 0;
+      Tag integer_tag = reader.ReadTag(&payload);  // read tag.
+      switch (integer_tag) {
+        case kBigIntLiteral: {
+          const String& value = H.DartString(reader.ReadStringReference());
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kSpecializedIntLiteral: {
+          const int64_t value =
+              static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kNegativeIntLiteral: {
+          const int64_t value = -static_cast<int64_t>(reader.ReadUInt());
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kPositiveIntLiteral: {
+          const int64_t value = reader.ReadUInt();
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        default:
+          H.ReportError(
+              script_, TokenPosition::kNoSource,
+              "Cannot lazily read integer: unexpected kernel tag %s (%d)",
+              Reader::TagName(integer_tag), integer_tag);
+      }
+      break;
+    }
+    case kDoubleConstant:
+      instance = Double::New(reader.ReadDouble(), Heap::kOld);
+      break;
+    case kStringConstant:
+      instance = H.DartSymbolPlain(reader.ReadStringReference()).raw();
+      break;
+    case kSymbolConstant: {
+      Library& library = Library::Handle(Z);
+      library = Library::InternalLibrary();
+      const Class& symbol_class =
+          Class::Handle(Z, library.LookupClass(Symbols::Symbol()));
+      const Field& symbol_name_field = Field::Handle(
+          Z, symbol_class.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+      ASSERT(!symbol_name_field.IsNull());
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      if (index == -1) {
+        library = Library::null();
+      } else {
+        library = H.LookupLibraryByKernelLibrary(index);
+      }
+      const String& symbol =
+          H.DartIdentifier(library, reader.ReadStringReference());
+      instance = Instance::New(symbol_class, Heap::kOld);
+      instance.SetField(symbol_name_field, symbol);
+      break;
+    }
+    case kListConstant: {
+      const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
+      const Class& list_class =
+          Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      TypeArguments& type_arguments =
+          TypeArguments::ZoneHandle(Z, TypeArguments::New(1, Heap::kOld));
+      AbstractType& type = type_translator.BuildType();
+      type_arguments.SetTypeAt(0, type);
+      // Instantiate class.
+      type = Type::New(list_class, type_arguments, TokenPosition::kNoSource);
+      type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+                                          ClassFinalizer::kCanonicalize);
+      type_arguments = type.arguments();
+      // Fill array with constant elements.
+      const intptr_t length = reader.ReadUInt();
+      const Array& array =
+          Array::Handle(Z, ImmutableArray::New(length, Heap::kOld));
+      array.SetTypeArguments(type_arguments);
+      Instance& constant = Instance::Handle(Z);
+      for (intptr_t j = 0; j < length; ++j) {
+        // Recurse into lazily evaluating all "sub" constants
+        // needed to evaluate the current constant.
+        const intptr_t entry_offset = reader.ReadUInt();
+        ASSERT(entry_offset < constant_offset);  // DAG!
+        constant = EvaluateConstantExpression(entry_offset);
+        array.SetAt(j, constant);
+      }
+      instance = array.raw();
+      break;
+    }
+    case kInstanceConstant: {
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      const Class& klass = Class::Handle(Z, H.LookupClassByKernelClass(index));
+      const Object& obj =
+          Object::Handle(Z, klass.EnsureIsFinalized(H.thread()));
+      ASSERT(obj.IsNull());
+      instance = Instance::New(klass, Heap::kOld);
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      const intptr_t number_of_type_arguments = reader.ReadUInt();
+      if (klass.NumTypeArguments() > 0) {
+        TypeArguments& type_arguments = TypeArguments::ZoneHandle(
+            Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+        for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+          type_arguments.SetTypeAt(j, type_translator.BuildType());
+        }
+        // Instantiate class.
+        AbstractType& type = AbstractType::Handle(
+            Z, Type::New(klass, type_arguments, TokenPosition::kNoSource));
+        type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+                                            ClassFinalizer::kCanonicalize);
+        type_arguments = type.arguments();
+        instance.SetTypeArguments(type_arguments);
+      } else {
+        ASSERT(number_of_type_arguments == 0);
+      }
+      // Set the fields.
+      const intptr_t number_of_fields = reader.ReadUInt();
+      Field& field = Field::Handle(Z);
+      Instance& constant = Instance::Handle(Z);
+      for (intptr_t j = 0; j < number_of_fields; ++j) {
+        field = H.LookupFieldByKernelField(reader.ReadCanonicalNameReference());
+        // Recurse into lazily evaluating all "sub" constants
+        // needed to evaluate the current constant.
+        const intptr_t entry_offset = reader.ReadUInt();
+        ASSERT(entry_offset < constant_offset);  // DAG!
+        constant = EvaluateConstantExpression(entry_offset);
+        instance.SetField(field, constant);
+      }
+      break;
+    }
+    case kPartialInstantiationConstant: {
+      // Recurse into lazily evaluating the "sub" constant
+      // needed to evaluate the current constant.
+      const intptr_t entry_offset = reader.ReadUInt();
+      ASSERT(entry_offset < constant_offset);  // DAG!
+      Instance& constant =
+          Instance::Handle(Z, EvaluateConstantExpression(entry_offset));
+      // Happens if the tearoff was in the vmservice library and we have
+      // [skip_vm_service_library] enabled.
+      if (constant.IsNull()) {
+        instance = Instance::null();
+        break;
+      }
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      const intptr_t number_of_type_arguments = reader.ReadUInt();
+      ASSERT(number_of_type_arguments > 0);
+      TypeArguments& type_arguments = TypeArguments::ZoneHandle(
+          Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+      for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+        type_arguments.SetTypeAt(j, type_translator.BuildType());
+      }
+      // Make a copy of the old closure, and set delayed type arguments.
+      Closure& closure = Closure::Handle(Z, Closure::RawCast(constant.raw()));
+      Function& function = Function::Handle(Z, closure.function());
+      TypeArguments& type_arguments2 =
+          TypeArguments::ZoneHandle(Z, closure.instantiator_type_arguments());
+      TypeArguments& type_arguments3 =
+          TypeArguments::ZoneHandle(Z, closure.function_type_arguments());
+      Context& context = Context::Handle(Z, closure.context());
+      instance = Closure::New(type_arguments2, Object::null_type_arguments(),
+                              type_arguments3, function, context,
+                              Heap::kOld);  // was type_arguments?
+      break;
+    }
+    case kTearOffConstant: {
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      Function& function =
+          Function::Handle(Z, H.LookupStaticMethodByKernelProcedure(index));
+      function = function.ImplicitClosureFunction();
+      instance = function.ImplicitStaticClosure();
+      break;
+    }
+    case kTypeLiteralConstant: {
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      instance = type_translator.BuildType().raw();
+      break;
+    }
+    default:
+      // Set literals (kSetConstant) are currently desugared in the frontend
+      // and will not reach the VM. See http://dartbug.com/35124 for some
+      // discussion. Map constants (kMapConstant ) are already lowered to
+      // InstanceConstant or ListConstant. We should never see unevaluated
+      // constants (kUnevaluatedConstant) in the constant table, they should
+      // have been fully evaluated before we get them.
+      H.ReportError(script_, TokenPosition::kNoSource,
+                    "Cannot lazily read constant: unexpected kernel tag (%" Pd
+                    ")",
+                    constant_tag);
+  }
+  return H.Canonicalize(instance);
+}
+
 void ConstantEvaluator::BailoutIfBackgroundCompilation() {
   if (Compiler::IsBackgroundCompilation()) {
     Compiler::AbortBackgroundCompilation(
@@ -868,20 +1112,6 @@
   result_ = Instance::null();
 }
 
-void ConstantEvaluator::EvaluateConstantExpression(Tag tag) {
-  // Please note that this constants array is constructed exactly once, see
-  // ReadConstantTable() and is immutable from that point on, so there is no
-  // need to guard against concurrent access between mutator and background
-  // compiler.
-  KernelConstantsMap constant_map(H.constants().raw());
-  if (tag == kConstantExpression) {
-    helper_->ReadPosition();
-    helper_->SkipDartType();
-  }
-  result_ ^= constant_map.GetOrDie(helper_->ReadUInt());
-  ASSERT(constant_map.Release().raw() == H.constants().raw());
-}
-
 // This depends on being about to read the list of positionals on arguments.
 const Object& ConstantEvaluator::RunFunction(TokenPosition position,
                                              const Function& function,
@@ -1109,273 +1339,6 @@
   }
 }
 
-ConstantHelper::ConstantHelper(Zone* zone,
-                               KernelReaderHelper* helper,
-                               TypeTranslator* type_translator,
-                               ActiveClass* active_class,
-                               NameIndex skip_vmservice_library)
-    : zone_(zone),
-      helper_(*helper),
-      type_translator_(*type_translator),
-      active_class_(active_class),
-      const_evaluator_(helper, type_translator, active_class, nullptr),
-      translation_helper_(helper->translation_helper_),
-      skip_vmservice_library_(skip_vmservice_library),
-      symbol_class_(Class::Handle(zone)),
-      symbol_name_field_(Field::Handle(zone)),
-      temp_type_(AbstractType::Handle(zone)),
-      temp_type_arguments_(TypeArguments::Handle(zone)),
-      temp_type_arguments2_(TypeArguments::Handle(zone)),
-      temp_type_arguments3_(TypeArguments::Handle(zone)),
-      temp_object_(Object::Handle(zone)),
-      temp_string_(String::Handle(zone)),
-      temp_array_(Array::Handle(zone)),
-      temp_instance_(Instance::Handle(zone)),
-      temp_field_(Field::Handle(zone)),
-      temp_class_(Class::Handle(zone)),
-      temp_library_(Library::Handle(zone)),
-      temp_function_(Function::Handle(zone)),
-      temp_closure_(Closure::Handle(zone)),
-      temp_context_(Context::Handle(zone)),
-      temp_integer_(Integer::Handle(zone)) {
-  temp_library_ = Library::InternalLibrary();
-  ASSERT(!temp_library_.IsNull());
-
-  symbol_class_ = temp_library_.LookupClass(Symbols::Symbol());
-  ASSERT(!symbol_class_.IsNull());
-
-  symbol_name_field_ =
-      symbol_class_.LookupInstanceFieldAllowPrivate(Symbols::_name());
-  ASSERT(!symbol_name_field_.IsNull());
-}
-
-const Array& ConstantHelper::ReadConstantTable() {
-  const intptr_t number_of_constants = helper_.ReadUInt();
-  if (number_of_constants == 0) {
-    return Array::empty_array();
-  }
-
-  const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
-  const Class& list_class =
-      Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
-
-  // Eagerly finalize _ImmutableList (instead of doing it on every list
-  // constant).
-  temp_class_ = I->class_table()->At(kImmutableArrayCid);
-  temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
-  ASSERT(temp_object_.IsNull());
-
-  KernelConstantsMap constants(
-      HashTables::New<KernelConstantsMap>(number_of_constants, Heap::kOld));
-
-  const intptr_t start_offset = helper_.ReaderOffset();
-
-  for (intptr_t i = 0; i < number_of_constants; ++i) {
-    const intptr_t offset = helper_.ReaderOffset();
-    const intptr_t constant_tag = helper_.ReadByte();
-    switch (constant_tag) {
-      case kNullConstant:
-        temp_instance_ = Instance::null();
-        break;
-      case kBoolConstant:
-        temp_instance_ = helper_.ReadByte() == 1 ? Object::bool_true().raw()
-                                                 : Object::bool_false().raw();
-        break;
-      case kIntConstant: {
-        temp_instance_ = const_evaluator_.EvaluateExpression(
-            helper_.ReaderOffset(), false /* reset position */);
-        break;
-      }
-      case kDoubleConstant: {
-        temp_instance_ = Double::New(helper_.ReadDouble(), Heap::kOld);
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kStringConstant: {
-        temp_instance_ =
-            H.Canonicalize(H.DartString(helper_.ReadStringReference()));
-        break;
-      }
-      case kSymbolConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (index == -1) {
-          temp_library_ = Library::null();
-        } else {
-          temp_library_ = H.LookupLibraryByKernelLibrary(index);
-        }
-        const String& symbol =
-            H.DartIdentifier(temp_library_, helper_.ReadStringReference());
-        temp_instance_ = Instance::New(symbol_class_, Heap::kOld);
-        temp_instance_.SetField(symbol_name_field_, symbol);
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kListConstant: {
-        temp_type_arguments_ = TypeArguments::New(1, Heap::kOld);
-        const AbstractType& type = type_translator_.BuildType();
-        temp_type_arguments_.SetTypeAt(0, type);
-        InstantiateTypeArguments(list_class, &temp_type_arguments_);
-
-        const intptr_t length = helper_.ReadUInt();
-        temp_array_ = ImmutableArray::New(length, Heap::kOld);
-        temp_array_.SetTypeArguments(temp_type_arguments_);
-        for (intptr_t j = 0; j < length; ++j) {
-          const intptr_t entry_offset = helper_.ReadUInt();
-          ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-          temp_object_ = constants.GetOrDie(entry_offset);
-          temp_array_.SetAt(j, temp_object_);
-        }
-
-        temp_instance_ = H.Canonicalize(temp_array_);
-        break;
-      }
-      case kSetConstant:
-        // Set literals are currently desugared in the frontend and will not
-        // reach the VM. See http://dartbug.com/35124 for discussion.
-        H.ReportError(script(), TokenPosition::kNoSource,
-                      "Unexpected set constant, this constant"
-                      " is expected to be evaluated at this point (%" Pd ")",
-                      constant_tag);
-        break;
-      case kInstanceConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (ShouldSkipConstant(index)) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        temp_class_ = H.LookupClassByKernelClass(index);
-        temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
-        ASSERT(temp_object_.IsNull());
-
-        temp_instance_ = Instance::New(temp_class_, Heap::kOld);
-
-        const intptr_t number_of_type_arguments = helper_.ReadUInt();
-        if (temp_class_.NumTypeArguments() > 0) {
-          temp_type_arguments_ =
-              TypeArguments::New(number_of_type_arguments, Heap::kOld);
-          for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
-            temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
-          }
-          InstantiateTypeArguments(temp_class_, &temp_type_arguments_);
-          temp_instance_.SetTypeArguments(temp_type_arguments_);
-        } else {
-          ASSERT(number_of_type_arguments == 0);
-        }
-
-        const intptr_t number_of_fields = helper_.ReadUInt();
-        for (intptr_t j = 0; j < number_of_fields; ++j) {
-          temp_field_ =
-              H.LookupFieldByKernelField(helper_.ReadCanonicalNameReference());
-          const intptr_t entry_offset = helper_.ReadUInt();
-          ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-          temp_object_ = constants.GetOrDie(entry_offset);
-          temp_instance_.SetField(temp_field_, temp_object_);
-        }
-
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kPartialInstantiationConstant: {
-        const intptr_t entry_offset = helper_.ReadUInt();
-        ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-        temp_object_ = constants.GetOrDie(entry_offset);
-
-        // Happens if the tearoff was in the vmservice library and we have
-        // [skip_vm_service_library] enabled.
-        if (temp_object_.IsNull()) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        const intptr_t number_of_type_arguments = helper_.ReadUInt();
-        ASSERT(number_of_type_arguments > 0);
-        temp_type_arguments_ =
-            TypeArguments::New(number_of_type_arguments, Heap::kOld);
-        for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
-          temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
-        }
-        temp_type_arguments_ = temp_type_arguments_.Canonicalize();
-
-        // Make a copy of the old closure, with the delayed type arguments
-        // set to [temp_type_arguments_].
-        temp_closure_ = Closure::RawCast(temp_object_.raw());
-        temp_function_ = temp_closure_.function();
-        temp_type_arguments2_ = temp_closure_.instantiator_type_arguments();
-        temp_type_arguments3_ = temp_closure_.function_type_arguments();
-        temp_context_ = temp_closure_.context();
-        temp_closure_ = Closure::New(
-            temp_type_arguments2_, Object::null_type_arguments(),
-            temp_type_arguments_, temp_function_, temp_context_, Heap::kOld);
-        temp_instance_ = H.Canonicalize(temp_closure_);
-        break;
-      }
-      case kTearOffConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (ShouldSkipConstant(index)) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        temp_function_ = H.LookupStaticMethodByKernelProcedure(index);
-        temp_function_ = temp_function_.ImplicitClosureFunction();
-        temp_instance_ = temp_function_.ImplicitStaticClosure();
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kTypeLiteralConstant: {
-        temp_instance_ = type_translator_.BuildType().raw();
-        break;
-      }
-      case kMapConstant:
-        // Note: This is already lowered to InstanceConstant/ListConstant.
-        H.ReportError(script(), TokenPosition::kNoSource,
-                      "Unexpected map constant, this constant"
-                      " is expected to be evaluated at this point (%" Pd ")",
-                      constant_tag);
-        break;
-      case kUnevaluatedConstant:
-        // We should not see unevaluated constants in the constant table, they
-        // should have been fully evaluated before we get them.
-        H.ReportError(
-            script(), TokenPosition::kNoSource,
-            "Unexpected unevaluated constant, All constant expressions"
-            " are expected to be evaluated at this point (%" Pd ")",
-            constant_tag);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    constants.InsertNewOrGetValue(offset - start_offset, temp_instance_);
-  }
-  return Array::Handle(Z, constants.Release().raw());
-}
-
-void ConstantHelper::InstantiateTypeArguments(const Class& receiver_class,
-                                              TypeArguments* 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)
-  temp_type_ =
-      Type::New(receiver_class, *type_arguments, TokenPosition::kNoSource);
-  temp_type_ = ClassFinalizer::FinalizeType(*active_class_->klass, temp_type_,
-                                            ClassFinalizer::kCanonicalize);
-  *type_arguments = temp_type_.arguments();
-}
-
-// If [index] has `dart:vm_service` as a parent and we are skipping the VM
-// service library, this method returns `true`, otherwise `false`.
-bool ConstantHelper::ShouldSkipConstant(NameIndex index) {
-  if (index == NameIndex::kInvalidName) {
-    return false;
-  }
-  while (!H.IsLibrary(index)) {
-    index = H.CanonicalNameParent(index);
-  }
-  ASSERT(H.IsLibrary(index));
-  return index == skip_vmservice_library_;
-}
-
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.h b/runtime/vm/compiler/frontend/constant_evaluator.h
index 0483baa..7981835 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.h
+++ b/runtime/vm/compiler/frontend/constant_evaluator.h
@@ -56,7 +56,13 @@
   RawObject* EvaluateExpressionSafe(intptr_t offset);
   RawObject* EvaluateAnnotations();
 
+  // Evaluates a constant at the given offset (possibly by recursing
+  // into sub-constants).
+  RawInstance* EvaluateConstantExpression(intptr_t constant_offset);
+
  private:
+  RawInstance* EvaluateConstant(intptr_t constant_offset);
+
   void BailoutIfBackgroundCompilation();
 
   bool IsBuildingFlowGraph() const;
@@ -88,7 +94,6 @@
   void EvaluateDoubleLiteral();
   void EvaluateBoolLiteral(bool value);
   void EvaluateNullLiteral();
-  void EvaluateConstantExpression(Tag tag);
 
   void EvaluateGetStringLength(intptr_t expression_offset,
                                TokenPosition position);
@@ -140,59 +145,6 @@
   DISALLOW_COPY_AND_ASSIGN(ConstantEvaluator);
 };
 
-// Helper class that reads a kernel Constant from binary.
-class ConstantHelper {
- public:
-  ConstantHelper(Zone* zone,
-                 KernelReaderHelper* helper,
-                 TypeTranslator* type_translator,
-                 ActiveClass* active_class,
-                 NameIndex skip_vmservice_library);
-
-  // Reads the constant table from the binary.
-  //
-  // This method assumes the Reader is positioned already at the constant table
-  // and an active class scope is setup.
-  const Array& ReadConstantTable();
-
- private:
-  const Script& script() const { return helper_.script_; }
-
-  void InstantiateTypeArguments(const Class& receiver_class,
-                                TypeArguments* type_arguments);
-
-  // If [index] has `dart:vm_service` as a parent and we are skipping the VM
-  // service library, this method returns `true`, otherwise `false`.
-  bool ShouldSkipConstant(NameIndex index);
-
-  Zone* zone_;
-  KernelReaderHelper& helper_;
-  TypeTranslator& type_translator_;
-  ActiveClass* const active_class_;
-  ConstantEvaluator const_evaluator_;
-  TranslationHelper& translation_helper_;
-  NameIndex skip_vmservice_library_;
-  Class& symbol_class_;
-  Field& symbol_name_field_;
-  AbstractType& temp_type_;
-  TypeArguments& temp_type_arguments_;
-  TypeArguments& temp_type_arguments2_;
-  TypeArguments& temp_type_arguments3_;
-  Object& temp_object_;
-  String& temp_string_;
-  Array& temp_array_;
-  Instance& temp_instance_;
-  Field& temp_field_;
-  Class& temp_class_;
-  Library& temp_library_;
-  Function& temp_function_;
-  Closure& temp_closure_;
-  Context& temp_context_;
-  Integer& temp_integer_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConstantHelper);
-};
-
 class KernelConstMapKeyEqualsTraits : public AllStatic {
  public:
   static const char* Name() { return "KernelConstMapKeyEqualsTraits"; }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d018655..89a647e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3776,10 +3776,8 @@
   }
   if (position != nullptr) *position = p;
   const intptr_t constant_offset = ReadUInt();
-  KernelConstantsMap constant_map(H.constants().raw());
-  Fragment result =
-      Constant(Object::ZoneHandle(Z, constant_map.GetOrDie(constant_offset)));
-  ASSERT(constant_map.Release().raw() == H.constants().raw());
+  Fragment result = Constant(Object::ZoneHandle(
+      Z, constant_evaluator_.EvaluateConstantExpression(constant_offset)));
   return result;
 }
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index d70628f..a3555db 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -32,6 +32,7 @@
       metadata_payloads_(ExternalTypedData::Handle(Z)),
       metadata_mappings_(ExternalTypedData::Handle(Z)),
       constants_(Array::Handle(Z)),
+      constants_table_(ExternalTypedData::Handle(Z)),
       info_(KernelProgramInfo::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)) {}
 
@@ -46,6 +47,7 @@
       metadata_payloads_(ExternalTypedData::Handle(Z)),
       metadata_mappings_(ExternalTypedData::Handle(Z)),
       constants_(Array::Handle(Z)),
+      constants_table_(ExternalTypedData::Handle(Z)),
       info_(KernelProgramInfo::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)) {}
 
@@ -79,6 +81,7 @@
   SetMetadataPayloads(ExternalTypedData::Handle(Z, info.metadata_payloads()));
   SetMetadataMappings(ExternalTypedData::Handle(Z, info.metadata_mappings()));
   SetConstants(Array::Handle(Z, info.constants()));
+  SetConstantsTable(ExternalTypedData::Handle(Z, info.constants_table()));
   SetKernelProgramInfo(info);
 }
 
@@ -126,6 +129,12 @@
   constants_ = constants.raw();
 }
 
+void TranslationHelper::SetConstantsTable(
+    const ExternalTypedData& constants_table) {
+  ASSERT(constants_table_.IsNull());
+  constants_table_ = constants_table.raw();
+}
+
 void TranslationHelper::SetKernelProgramInfo(const KernelProgramInfo& info) {
   info_ = info.raw();
 }
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 1dc3f3c4..43efd07 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -41,24 +41,35 @@
   Heap::Space allocation_space() { return allocation_space_; }
 
   // Access to strings.
-  const TypedData& string_offsets() { return string_offsets_; }
+  const TypedData& string_offsets() const { return string_offsets_; }
   void SetStringOffsets(const TypedData& string_offsets);
 
-  const ExternalTypedData& string_data() { return string_data_; }
+  const ExternalTypedData& string_data() const { return string_data_; }
   void SetStringData(const ExternalTypedData& string_data);
 
-  const TypedData& canonical_names() { return canonical_names_; }
+  const TypedData& canonical_names() const { return canonical_names_; }
   void SetCanonicalNames(const TypedData& canonical_names);
 
-  const ExternalTypedData& metadata_payloads() { return metadata_payloads_; }
+  const ExternalTypedData& metadata_payloads() const {
+    return metadata_payloads_;
+  }
   void SetMetadataPayloads(const ExternalTypedData& metadata_payloads);
 
-  const ExternalTypedData& metadata_mappings() { return metadata_mappings_; }
+  const ExternalTypedData& metadata_mappings() const {
+    return metadata_mappings_;
+  }
   void SetMetadataMappings(const ExternalTypedData& metadata_mappings);
 
+  // Access to previously evaluated constants from the constants table.
   const Array& constants() { return constants_; }
   void SetConstants(const Array& constants);
 
+  // Access to the raw bytes of the constants table.
+  const ExternalTypedData& constants_table() const { return constants_table_; }
+  void SetConstantsTable(const ExternalTypedData& constants_table);
+
+  KernelProgramInfo& info() { return info_; }
+
   RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
 
   void SetKernelProgramInfo(const KernelProgramInfo& info);
@@ -206,6 +217,7 @@
   ExternalTypedData& metadata_payloads_;
   ExternalTypedData& metadata_mappings_;
   Array& constants_;
+  ExternalTypedData& constants_table_;
   KernelProgramInfo& info_;
   Smi& name_index_handle_;
 
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index d37c67d..f7ce8e0 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -190,6 +190,7 @@
       zone_(thread_->zone()),
       isolate_(thread_->isolate()),
       patch_classes_(Array::ZoneHandle(zone_)),
+      active_class_(),
       library_kernel_offset_(-1),  // Set to the correct value in LoadLibrary
       correction_offset_(-1),      // Set to the correct value in LoadLibrary
       loading_native_wrappers_library_(false),
@@ -206,6 +207,7 @@
       bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
+      evaluating_(GrowableObjectArray::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
       potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
@@ -455,6 +457,7 @@
       bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
+      evaluating_(GrowableObjectArray::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
       potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
@@ -472,32 +475,6 @@
   H.InitFromKernelProgramInfo(kernel_program_info_);
 }
 
-const Array& KernelLoader::ReadConstantTable() {
-  if (program_->library_count() == 0) {
-    return Array::empty_array();
-  }
-  // We use the very first library's toplevel class as an owner for an
-  // [ActiveClassScope]
-  //
-  // Though since constants cannot refer to types containing type parameter
-  // references, the only purpose of the class is to serve as an owner for
-  // signature functions (which get created for function types).
-  const dart::Library& owner_library =
-      Library::Handle(Z, LookupLibrary(library_canonical_name(0)));
-  const dart::Class& toplevel_class =
-      Class::Handle(Z, owner_library.toplevel_class());
-  ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
-
-  helper_.SetOffset(program_->constant_table_offset());
-  TypeTranslator type_translator_(&helper_, &active_class_,
-                                  true /* finalize */);
-  ASSERT(type_translator_.active_class_ == &active_class_);
-
-  ConstantHelper helper(Z, &helper_, &type_translator_, &active_class_,
-                        skip_vmservice_library_);
-  return helper.ReadConstantTable();
-}
-
 void KernelLoader::EvaluateDelayedPragmas() {
   potential_pragma_functions_ =
       kernel_program_info_.potential_pragma_functions();
@@ -522,66 +499,68 @@
       GrowableObjectArray::Handle(Z));
 }
 
-void KernelLoader::AnnotateNativeProcedures(const Array& constant_table_array) {
-  KernelConstantsMap constant_table(constant_table_array.raw());
+void KernelLoader::AnnotateNativeProcedures() {
   potential_natives_ = kernel_program_info_.potential_natives();
   const intptr_t length =
       !potential_natives_.IsNull() ? potential_natives_.Length() : 0;
-  if (length > 0) {
-    // Obtain `dart:_internal::ExternalName.name`.
-    EnsureExternalClassIsLookedUp();
-    Instance& constant = Instance::Handle(Z);
-    String& native_name = String::Handle(Z);
+  if (length == 0) return;
 
-    // Start scanning all candidates in [potential_natives] for the annotation
-    // constant.  If the annotation is found, flag the [Function] as native and
-    // attach the native name to it.
-    Function& function = Function::Handle(Z);
-    for (intptr_t i = 0; i < length; ++i) {
-      function ^= potential_natives_.At(i);
-      helper_.SetOffset(function.KernelDataProgramOffset() +
-                        function.kernel_offset());
-      {
-        ProcedureHelper procedure_helper(&helper_);
-        procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
-      }
+  // Prepare lazy constant reading.
+  ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                       &active_class_);
 
-      const intptr_t annotation_count = helper_.ReadListLength();
-      for (intptr_t j = 0; j < annotation_count; ++j) {
-        const intptr_t tag = helper_.PeekTag();
-        if (tag == kConstantExpression ||
-            tag == kDeprecated_ConstantExpression) {
-          helper_.ReadByte();  // Skip the tag.
+  // Obtain `dart:_internal::ExternalName.name`.
+  EnsureExternalClassIsLookedUp();
+  Instance& constant = Instance::Handle(Z);
+  String& native_name = String::Handle(Z);
 
-          // We have a candiate.  Let's look if it's an instance of the
-          // ExternalName class.
-          if (tag == kConstantExpression) {
-            helper_.ReadPosition();  // Skip fileOffset.
-            helper_.SkipDartType();  // Skip type.
-          }
-          const intptr_t constant_table_offset = helper_.ReadUInt();
-          constant ^= constant_table.GetOrDie(constant_table_offset);
-          if (constant.clazz() == external_name_class_.raw()) {
-            // We found the annotation, let's flag the function as native and
-            // set the native name!
-            native_name ^= constant.GetField(external_name_field_);
-            function.set_is_native(true);
-            function.set_native_name(native_name);
-            function.set_is_external(false);
-            break;
-          }
-        } else {
-          helper_.SkipExpression();
-        }
-      }
+  // Start scanning all candidates in [potential_natives] for the annotation
+  // constant.  If the annotation is found, flag the [Function] as native and
+  // attach the native name to it.
+  Function& function = Function::Handle(Z);
+  for (intptr_t i = 0; i < length; ++i) {
+    function ^= potential_natives_.At(i);
+    helper_.SetOffset(function.KernelDataProgramOffset() +
+                      function.kernel_offset());
+    {
+      ProcedureHelper procedure_helper(&helper_);
+      procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
     }
 
-    // Clear out the list of [Function] objects which might need their native
-    // name to be set after reading the constant table from the kernel blob.
-    potential_natives_ = GrowableObjectArray::null();
-    kernel_program_info_.set_potential_natives(potential_natives_);
+    const intptr_t annotation_count = helper_.ReadListLength();
+    for (intptr_t j = 0; j < annotation_count; ++j) {
+      const intptr_t tag = helper_.PeekTag();
+      if (tag == kConstantExpression || tag == kDeprecated_ConstantExpression) {
+        helper_.ReadByte();  // Skip the tag.
+
+        // We have a candidate.  Let's look if it's an instance of the
+        // ExternalName class.
+        if (tag == kConstantExpression) {
+          helper_.ReadPosition();  // Skip fileOffset.
+          helper_.SkipDartType();  // Skip type.
+        }
+        const intptr_t constant_table_offset = helper_.ReadUInt();
+        constant = constant_evaluator.EvaluateConstantExpression(
+            constant_table_offset);
+        if (constant.clazz() == external_name_class_.raw()) {
+          // We found the annotation, let's flag the function as native and
+          // set the native name!
+          native_name ^= constant.GetField(external_name_field_);
+          function.set_is_native(true);
+          function.set_native_name(native_name);
+          function.set_is_external(false);
+          break;
+        }
+      } else {
+        helper_.SkipExpression();
+      }
+    }
   }
-  ASSERT(constant_table.Release().raw() == constant_table_array.raw());
+
+  // Clear out the list of [Function] objects which might need their native
+  // name to be set after reading the constant table from the kernel blob.
+  potential_natives_ = GrowableObjectArray::null();
+  kernel_program_info_.set_potential_natives(potential_natives_);
 }
 
 RawString* KernelLoader::DetectExternalNameCtor() {
@@ -638,14 +617,15 @@
   return IsClassName(annotation_class, Symbols::DartCore(), Symbols::Pragma());
 }
 
-void KernelLoader::LoadNativeExtensionLibraries(
-    const Array& constant_table_array) {
+void KernelLoader::LoadNativeExtensionLibraries() {
   const intptr_t length = !potential_extension_libraries_.IsNull()
                               ? potential_extension_libraries_.Length()
                               : 0;
   if (length == 0) return;
 
-  KernelConstantsMap constant_table(constant_table_array.raw());
+  // Prepare lazy constant reading.
+  ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                       &active_class_);
 
   // Obtain `dart:_internal::ExternalName.name`.
   EnsureExternalClassIsLookedUp();
@@ -677,8 +657,9 @@
           helper_.ReadPosition();  // Skip fileOffset.
           helper_.SkipDartType();  // Skip type.
         }
-        const intptr_t constant_table_index = helper_.ReadUInt();
-        constant ^= constant_table.GetOrDie(constant_table_index);
+        const intptr_t constant_table_offset = helper_.ReadUInt();
+        constant = constant_evaluator.EvaluateConstantExpression(
+            constant_table_offset);
         if (constant.clazz() == external_name_class_.raw()) {
           uri_path ^= constant.GetField(external_name_field_);
         }
@@ -716,7 +697,6 @@
     }
   }
   potential_extension_libraries_ = GrowableObjectArray::null();
-  ASSERT(constant_table.Release().raw() == constant_table_array.raw());
 }
 
 RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
@@ -743,6 +723,7 @@
       }
     }
 
+    // Finalize still pending classes if requested.
     if (process_pending_classes) {
       if (!ClassFinalizer::ProcessPendingClasses()) {
         // Class finalization failed -> sticky error would be set.
@@ -750,44 +731,17 @@
       }
     }
 
-    // Set pending fields array to flag constant table loading.
-    ASSERT(I->object_store()->pending_unevaluated_const_fields() ==
-           GrowableObjectArray::null());
-    GrowableObjectArray& pending_unevaluated_const_fields =
-        GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
-    I->object_store()->set_pending_unevaluated_const_fields(
-        pending_unevaluated_const_fields);
-
-    // All classes were successfully loaded, so let's:
-    //     a) load & canonicalize the constant table
-    const Array& constants = ReadConstantTable();
-
-    //     b) set the native names for native functions which have been created
-    //        so far (the rest will be directly set during LoadProcedure)
-    AnnotateNativeProcedures(constants);
-    LoadNativeExtensionLibraries(constants);
-
-    //     c) update all scripts with the constants array
-    ASSERT(kernel_program_info_.constants() == Array::null());
-    kernel_program_info_.set_constants(constants);
-    kernel_program_info_.set_constants_table(ExternalTypedData::Handle(Z));
-
-    //     d) evaluate pending field initializers
-    Error& error = Error::Handle(Z);
-    Field& field = Field::Handle(Z);
-    for (intptr_t i = 0, n = pending_unevaluated_const_fields.Length(); i < n;
-         i++) {
-      field ^= pending_unevaluated_const_fields.At(i);
-      error = field.Initialize();
-      if (!error.IsNull()) {
-        H.ReportError(error, "postponed field initializer");
-      }
-    }
-    pending_unevaluated_const_fields = GrowableObjectArray::null();
-    I->object_store()->set_pending_unevaluated_const_fields(
-        pending_unevaluated_const_fields);
-
-    //     e) evaluate pragmas that were delayed
+    // Sets the constants array to an empty hash and leaves the constant
+    // table's raw bytes in place for lazy reading. We can fix up all
+    // "pending" processing now, and must ensure we don't create new
+    // ones from this point on.
+    ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
+    const Array& array =
+        Array::Handle(Z, HashTables::New<KernelConstantsMap>(16, Heap::kOld));
+    kernel_program_info_.set_constants(array);
+    H.SetConstants(array);  // for caching
+    AnnotateNativeProcedures();
+    LoadNativeExtensionLibraries();
     EvaluateDelayedPragmas();
 
     NameIndex main = program_->main_method();
@@ -1067,6 +1021,8 @@
       helper_.ReaderOffset() - correction_offset_;
   intptr_t annotation_count = helper_.ReadListLength();  // read list length.
   if (annotation_count > 0) {
+    // This must wait until we can evaluate constants.
+    // So put on the "pending" list.
     EnsurePotentialExtensionLibraries();
     potential_extension_libraries_.Add(library);
   }
@@ -1148,7 +1104,6 @@
   if (toplevel_class.is_loaded()) {
     return;
   }
-
   TIMELINE_DURATION(Thread::Current(), Isolate, "FinishTopLevelClassLoading");
 
   ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
@@ -1190,7 +1145,7 @@
     {
       String& native_name_unused = String::Handle();
       bool is_potential_native_unused;
-      ReadVMAnnotations(annotation_count, &native_name_unused,
+      ReadVMAnnotations(library, annotation_count, &native_name_unused,
                         &is_potential_native_unused, &has_pragma_annotation);
     }
     field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1451,7 +1406,7 @@
   {
     String& native_name_unused = String::Handle(Z);
     bool is_potential_native_unused = false;
-    ReadVMAnnotations(annotation_count, &native_name_unused,
+    ReadVMAnnotations(library, annotation_count, &native_name_unused,
                       &is_potential_native_unused, &has_pragma_annotation);
   }
   if (has_pragma_annotation) {
@@ -1545,7 +1500,7 @@
       {
         String& native_name_unused = String::Handle();
         bool is_potential_native_unused;
-        ReadVMAnnotations(annotation_count, &native_name_unused,
+        ReadVMAnnotations(library, annotation_count, &native_name_unused,
                           &is_potential_native_unused, &has_pragma_annotation);
       }
       field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1618,7 +1573,7 @@
     {
       String& native_name_unused = String::Handle();
       bool is_potential_native_unused;
-      ReadVMAnnotations(annotation_count, &native_name_unused,
+      ReadVMAnnotations(library, annotation_count, &native_name_unused,
                         &is_potential_native_unused, &has_pragma_annotation);
     }
     constructor_helper.SetJustRead(ConstructorHelper::kAnnotations);
@@ -1760,12 +1715,14 @@
 //   `has_pragma_annotation`: non-null if @pragma(...) was found (no information
 //   is given on the kind of pragma directive).
 //
-void KernelLoader::ReadVMAnnotations(intptr_t annotation_count,
+void KernelLoader::ReadVMAnnotations(const Library& library,
+                                     intptr_t annotation_count,
                                      String* native_name,
                                      bool* is_potential_native,
                                      bool* has_pragma_annotation) {
   *is_potential_native = false;
   *has_pragma_annotation = false;
+  Instance& constant = Instance::Handle(Z);
   String& detected_name = String::Handle(Z);
   for (intptr_t i = 0; i < annotation_count; ++i) {
     const intptr_t tag = helper_.PeekTag();
@@ -1828,7 +1785,13 @@
                           Symbols::DartCore(), Symbols::Pragma());
         }
       } else {
-        KernelConstantsMap constant_table(constant_table_array.raw());
+        // Prepare lazy constant reading.
+        const dart::Class& toplevel_class =
+            Class::Handle(Z, library.toplevel_class());
+        ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
+        ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                             &active_class_);
+
         helper_.ReadByte();  // Skip the tag.
 
         // Obtain `dart:_internal::ExternalName.name`.
@@ -1841,18 +1804,27 @@
           helper_.ReadPosition();  // Skip fileOffset.
           helper_.SkipDartType();  // Skip type.
         }
-        const intptr_t constant_table_index = helper_.ReadUInt();
-        const Object& constant =
-            Object::Handle(constant_table.GetOrDie(constant_table_index));
-        if (constant.clazz() == external_name_class_.raw()) {
-          const Instance& instance =
-              Instance::Handle(Instance::RawCast(constant.raw()));
-          *native_name =
-              String::RawCast(instance.GetField(external_name_field_));
-        } else if (constant.clazz() == pragma_class_.raw()) {
-          *has_pragma_annotation = true;
+        const intptr_t constant_table_offset = helper_.ReadUInt();
+        // A cycle in evaluating the same library instance occurs when we are
+        // trying to finalize a class while evaluation the constant. We break
+        // this cycle by ignoring the second evaluation, since the first
+        // evaluation will take care of inspecting the result.
+        // TODO(ajcbik): avoid cycle detection completely by peeking
+        //               into the constants and proceed only for @pragma
+        //               or @ExternalName
+        if (EnqueueLibraryForEvaluation(library)) {
+          constant = constant_evaluator.EvaluateConstantExpression(
+              constant_table_offset);
+          DequeueLibraryForEvaluation(library);
+          if (constant.clazz() == external_name_class_.raw()) {
+            const Instance& instance =
+                Instance::Handle(Instance::RawCast(constant.raw()));
+            *native_name =
+                String::RawCast(instance.GetField(external_name_field_));
+          } else if (constant.clazz() == pragma_class_.raw()) {
+            *has_pragma_annotation = true;
+          }
         }
-        ASSERT(constant_table.Release().raw() == constant_table_array.raw());
       }
     } else {
       helper_.SkipExpression();
@@ -1881,8 +1853,8 @@
   bool is_potential_native;
   bool has_pragma_annotation;
   const intptr_t annotation_count = helper_.ReadListLength();
-  ReadVMAnnotations(annotation_count, &native_name, &is_potential_native,
-                    &has_pragma_annotation);
+  ReadVMAnnotations(library, annotation_count, &native_name,
+                    &is_potential_native, &has_pragma_annotation);
   // If this is a potential native, we'll unset is_external in
   // AnnotateNativeProcedures instead.
   is_external = is_external && native_name.IsNull();
@@ -1959,6 +1931,7 @@
     function.set_native_name(native_name);
   }
   if (is_potential_native) {
+    // Cannot be processed right now, so put on "pending" list.
     EnsurePotentialNatives();
     potential_natives_.Add(function);
   }
@@ -1979,6 +1952,8 @@
 
   if (has_pragma_annotation) {
     if (kernel_program_info_.constants() == Array::null()) {
+      // Any potential pragma function before point at which
+      // constant table could be loaded goes to "pending".
       EnsurePotentialPragmaFunctions();
       potential_pragma_functions_.Add(function);
     } else {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index f6d7665..5eb7442 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -230,8 +230,6 @@
 
   void ReadObfuscationProhibitions();
 
-  const Array& ReadConstantTable();
-
   // Check for the presence of a (possibly const) constructor for the
   // 'ExternalName' class. If found, returns the name parameter to the
   // constructor.
@@ -243,11 +241,12 @@
 
   bool IsClassName(NameIndex name, const String& library, const String& klass);
 
-  void AnnotateNativeProcedures(const Array& constant_table);
-  void LoadNativeExtensionLibraries(const Array& constant_table);
+  void AnnotateNativeProcedures();
+  void LoadNativeExtensionLibraries();
   void EvaluateDelayedPragmas();
 
-  void ReadVMAnnotations(intptr_t annotation_count,
+  void ReadVMAnnotations(const Library& library,
+                         intptr_t annotation_count,
                          String* native_name,
                          bool* is_potential_native,
                          bool* has_pragma_annotation);
@@ -396,6 +395,37 @@
     }
   }
 
+  // Returns `true` if the [library] was newly enqueued or `false`
+  // if it was already enqueued. Allocates storage on first enqueue.
+  bool EnqueueLibraryForEvaluation(const Library& library) {
+    evaluating_ = kernel_program_info_.evaluating();
+    if (evaluating_.IsNull()) {
+      evaluating_ = GrowableObjectArray::New();
+      kernel_program_info_.set_evaluating(evaluating_);
+      ASSERT(!evaluating_.IsNull());
+    } else {
+      for (intptr_t i = 0, n = evaluating_.Length(); i < n; i++) {
+        if (library.raw() == evaluating_.At(i)) {
+          return false;
+        }
+      }
+    }
+    evaluating_.Add(library);
+    return true;
+  }
+
+  // Dequeues most recent libary. Releases storage when empty.
+  void DequeueLibraryForEvaluation(const Library& library) {
+    ASSERT(!evaluating_.IsNull());
+    RawObject* object = evaluating_.RemoveLast();
+    ASSERT(library.raw() == object);
+    if (evaluating_.Length() == 0) {
+      evaluating_ = GrowableObjectArray::null();
+      kernel_program_info_.set_evaluating(evaluating_);
+      ASSERT(evaluating_.IsNull());
+    }
+  }
+
   Program* program_;
 
   Thread* thread_;
@@ -423,6 +453,7 @@
 
   Class& external_name_class_;
   Field& external_name_field_;
+  GrowableObjectArray& evaluating_;
   GrowableObjectArray& potential_natives_;
   GrowableObjectArray& potential_pragma_functions_;
   GrowableObjectArray& potential_extension_libraries_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e98d24c..adba2b0 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -12149,6 +12149,11 @@
   StorePointer(&raw_ptr()->constants_table_, value.raw());
 }
 
+void KernelProgramInfo::set_evaluating(
+    const GrowableObjectArray& evaluating) const {
+  StorePointer(&raw_ptr()->evaluating_, evaluating.raw());
+}
+
 void KernelProgramInfo::set_potential_natives(
     const GrowableObjectArray& candidates) const {
   StorePointer(&raw_ptr()->potential_natives_, candidates.raw());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index bbfa0f7..58f52b3 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4402,6 +4402,10 @@
   RawArray* constants() const { return raw_ptr()->constants_; }
   void set_constants(const Array& constants) const;
 
+  // Records libraries under evaluation to break evaluation cycles.
+  RawGrowableObjectArray* evaluating() const { return raw_ptr()->evaluating_; }
+  void set_evaluating(const GrowableObjectArray& evaluating) const;
+
   // If we load a kernel blob with evaluated constants, then we delay setting
   // the native names of [Function] objects until we've read the constant table
   // (since native names are encoded as constants).
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 88dfaf9..a13c5ba6 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1258,6 +1258,7 @@
   RawArray* bytecode_component_;
   RawGrowableObjectArray* potential_natives_;
   RawGrowableObjectArray* potential_pragma_functions_;
+  RawGrowableObjectArray* evaluating_;  // detects cycles
   RawExternalTypedData* constants_table_;
   RawArray* libraries_cache_;
   RawArray* classes_cache_;
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 35d4fdc..c3a3410 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -93,6 +93,7 @@
   F(KernelProgramInfo, bytecode_component_)                                    \
   F(KernelProgramInfo, potential_natives_)                                     \
   F(KernelProgramInfo, potential_pragma_functions_)                            \
+  F(KernelProgramInfo, evaluating_)                                            \
   F(KernelProgramInfo, constants_table_)                                       \
   F(KernelProgramInfo, libraries_cache_)                                       \
   F(KernelProgramInfo, classes_cache_)                                         \
