blob: 019c12b0373609ab9caade76207949ce805642fc [file] [log] [blame]
// Copyright (c) 2020, 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 <functional>
#include "vm/allocation.h"
#include "vm/token_position.h"
namespace dart {
class Class;
class Function;
class FunctionPtr;
// Implementation of cache for inner closure functions.
// This cache is populated lazily by the compiler: When compiling a function,
// the flow graph builder will recursively traverse the kernel AST for the
// function and any inner functions. This will cause the lazy-creation of inner
// closure functions.
// The cache is currently implemented as O(n) lookup in a growable list.
// Parts of the VM have certain requirements that are maintained:
// * parent functions need to come before inner functions
// * closure functions list can grow while iterating
// * the index of closure function must be stable
// If the linear lookup turns out to be too expensive, the list of closures
// could be maintained in a hash map, with the key being the token position of
// the closure. There are almost no collisions with this simple hash value.
// However, iterating over all closure functions becomes more difficult,
// especially when the list/map changes while iterating over it (see
// requirements above).
class ClosureFunctionsCache : public AllStatic {
static FunctionPtr LookupClosureFunction(const Class& owner,
TokenPosition pos);
static FunctionPtr LookupClosureFunctionLocked(const Class& owner,
TokenPosition pos);
static FunctionPtr LookupClosureFunction(const Function& parent,
TokenPosition token_pos);
static FunctionPtr LookupClosureFunctionLocked(const Function& parent,
TokenPosition token_pos);
static void AddClosureFunctionLocked(const Function& function);
static intptr_t FindClosureIndex(const Function& needle);
static FunctionPtr ClosureFunctionFromIndex(intptr_t idx);
static FunctionPtr GetUniqueInnerClosure(const Function& outer);
// Visits all closure functions registered in the object store.
// Iterates in-order, thereby allowing new closures being added during the
// iteration.
// The iteration continues until either [callback] returns `false` or all
// closure functions have been visited.
static void ForAllClosureFunctions(
std::function<bool(const Function&)> callback);
} // namespace dart