1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/heap/code-object-registry.h" 6 7#include <algorithm> 8 9#include "src/base/logging.h" 10 11namespace v8 { 12namespace internal { 13 14void CodeObjectRegistry::RegisterNewlyAllocatedCodeObject(Address code) { 15 base::MutexGuard guard(&code_object_registry_mutex_); 16 if (is_sorted_) { 17 is_sorted_ = 18 (code_object_registry_.empty() || code_object_registry_.back() < code); 19 } 20 code_object_registry_.push_back(code); 21} 22 23void CodeObjectRegistry::RegisterAlreadyExistingCodeObject(Address code) { 24 // This function is not protected by the mutex, and should only be called 25 // by the sweeper. 26 DCHECK(is_sorted_); 27 DCHECK(code_object_registry_.empty() || code_object_registry_.back() < code); 28 code_object_registry_.push_back(code); 29} 30 31void CodeObjectRegistry::Clear() { 32 // This function is not protected by the mutex, and should only be called 33 // by the sweeper. 34 code_object_registry_.clear(); 35 is_sorted_ = true; 36} 37 38void CodeObjectRegistry::Finalize() { 39 // This function is not protected by the mutex, and should only be called 40 // by the sweeper. 41 DCHECK(is_sorted_); 42 code_object_registry_.shrink_to_fit(); 43} 44 45bool CodeObjectRegistry::Contains(Address object) const { 46 base::MutexGuard guard(&code_object_registry_mutex_); 47 if (!is_sorted_) { 48 std::sort(code_object_registry_.begin(), code_object_registry_.end()); 49 is_sorted_ = true; 50 } 51 return (std::binary_search(code_object_registry_.begin(), 52 code_object_registry_.end(), object)); 53} 54 55Address CodeObjectRegistry::GetCodeObjectStartFromInnerAddress( 56 Address address) const { 57 base::MutexGuard guard(&code_object_registry_mutex_); 58 if (!is_sorted_) { 59 std::sort(code_object_registry_.begin(), code_object_registry_.end()); 60 is_sorted_ = true; 61 } 62 63 // The code registry can't be empty, else the code object can't exist. 64 DCHECK(!code_object_registry_.empty()); 65 66 // std::upper_bound returns the first code object strictly greater than 67 // address, so the code object containing the address has to be the previous 68 // one. 69 auto it = std::upper_bound(code_object_registry_.begin(), 70 code_object_registry_.end(), address); 71 // The address has to be contained in a code object, so necessarily the 72 // address can't be smaller than the first code object. 73 DCHECK_NE(it, code_object_registry_.begin()); 74 return *(--it); 75} 76 77} // namespace internal 78} // namespace v8 79