11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/heap/code-object-registry.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <algorithm>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "src/base/logging.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace v8 {
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_civoid CodeObjectRegistry::RegisterNewlyAllocatedCodeObject(Address code) {
151cb0ef41Sopenharmony_ci  base::MutexGuard guard(&code_object_registry_mutex_);
161cb0ef41Sopenharmony_ci  if (is_sorted_) {
171cb0ef41Sopenharmony_ci    is_sorted_ =
181cb0ef41Sopenharmony_ci        (code_object_registry_.empty() || code_object_registry_.back() < code);
191cb0ef41Sopenharmony_ci  }
201cb0ef41Sopenharmony_ci  code_object_registry_.push_back(code);
211cb0ef41Sopenharmony_ci}
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_civoid CodeObjectRegistry::RegisterAlreadyExistingCodeObject(Address code) {
241cb0ef41Sopenharmony_ci  // This function is not protected by the mutex, and should only be called
251cb0ef41Sopenharmony_ci  // by the sweeper.
261cb0ef41Sopenharmony_ci  DCHECK(is_sorted_);
271cb0ef41Sopenharmony_ci  DCHECK(code_object_registry_.empty() || code_object_registry_.back() < code);
281cb0ef41Sopenharmony_ci  code_object_registry_.push_back(code);
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_civoid CodeObjectRegistry::Clear() {
321cb0ef41Sopenharmony_ci  // This function is not protected by the mutex, and should only be called
331cb0ef41Sopenharmony_ci  // by the sweeper.
341cb0ef41Sopenharmony_ci  code_object_registry_.clear();
351cb0ef41Sopenharmony_ci  is_sorted_ = true;
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_civoid CodeObjectRegistry::Finalize() {
391cb0ef41Sopenharmony_ci  // This function is not protected by the mutex, and should only be called
401cb0ef41Sopenharmony_ci  // by the sweeper.
411cb0ef41Sopenharmony_ci  DCHECK(is_sorted_);
421cb0ef41Sopenharmony_ci  code_object_registry_.shrink_to_fit();
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_cibool CodeObjectRegistry::Contains(Address object) const {
461cb0ef41Sopenharmony_ci  base::MutexGuard guard(&code_object_registry_mutex_);
471cb0ef41Sopenharmony_ci  if (!is_sorted_) {
481cb0ef41Sopenharmony_ci    std::sort(code_object_registry_.begin(), code_object_registry_.end());
491cb0ef41Sopenharmony_ci    is_sorted_ = true;
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci  return (std::binary_search(code_object_registry_.begin(),
521cb0ef41Sopenharmony_ci                             code_object_registry_.end(), object));
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ciAddress CodeObjectRegistry::GetCodeObjectStartFromInnerAddress(
561cb0ef41Sopenharmony_ci    Address address) const {
571cb0ef41Sopenharmony_ci  base::MutexGuard guard(&code_object_registry_mutex_);
581cb0ef41Sopenharmony_ci  if (!is_sorted_) {
591cb0ef41Sopenharmony_ci    std::sort(code_object_registry_.begin(), code_object_registry_.end());
601cb0ef41Sopenharmony_ci    is_sorted_ = true;
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  // The code registry can't be empty, else the code object can't exist.
641cb0ef41Sopenharmony_ci  DCHECK(!code_object_registry_.empty());
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  // std::upper_bound returns the first code object strictly greater than
671cb0ef41Sopenharmony_ci  // address, so the code object containing the address has to be the previous
681cb0ef41Sopenharmony_ci  // one.
691cb0ef41Sopenharmony_ci  auto it = std::upper_bound(code_object_registry_.begin(),
701cb0ef41Sopenharmony_ci                             code_object_registry_.end(), address);
711cb0ef41Sopenharmony_ci  // The address has to be contained in a code object, so necessarily the
721cb0ef41Sopenharmony_ci  // address can't be smaller than the first code object.
731cb0ef41Sopenharmony_ci  DCHECK_NE(it, code_object_registry_.begin());
741cb0ef41Sopenharmony_ci  return *(--it);
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci}  // namespace internal
781cb0ef41Sopenharmony_ci}  // namespace v8
79