// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/heap/code-object-registry.h" #include <algorithm> #include "src/base/logging.h" namespace v8 { namespace internal { void CodeObjectRegistry::RegisterNewlyAllocatedCodeObject(Address code) { auto result = code_object_registry_newly_allocated_.insert(code); USE(result); DCHECK(result.second); } void CodeObjectRegistry::RegisterAlreadyExistingCodeObject(Address code) { code_object_registry_already_existing_.push_back(code); } void CodeObjectRegistry::Clear() { code_object_registry_already_existing_.clear(); code_object_registry_newly_allocated_.clear(); } void CodeObjectRegistry::Finalize() { code_object_registry_already_existing_.shrink_to_fit(); } bool CodeObjectRegistry::Contains(Address object) const { return (code_object_registry_newly_allocated_.find(object) != code_object_registry_newly_allocated_.end()) || (std::binary_search(code_object_registry_already_existing_.begin(), code_object_registry_already_existing_.end(), object)); } Address CodeObjectRegistry::GetCodeObjectStartFromInnerAddress( Address address) const { // Let's first find the object which comes right before address in the vector // of already existing code objects. Address already_existing_set_ = 0; Address newly_allocated_set_ = 0; if (!code_object_registry_already_existing_.empty()) { auto it = std::upper_bound(code_object_registry_already_existing_.begin(), code_object_registry_already_existing_.end(), address); if (it != code_object_registry_already_existing_.begin()) { already_existing_set_ = *(--it); } } // Next, let's find the object which comes right before address in the set // of newly allocated code objects. if (!code_object_registry_newly_allocated_.empty()) { auto it = code_object_registry_newly_allocated_.upper_bound(address); if (it != code_object_registry_newly_allocated_.begin()) { newly_allocated_set_ = *(--it); } } // The code objects which contains address has to be in one of the two // data structures. DCHECK(already_existing_set_ != 0 || newly_allocated_set_ != 0); // The address which is closest to the given address is the code object. return already_existing_set_ > newly_allocated_set_ ? already_existing_set_ : newly_allocated_set_; } } // namespace internal } // namespace v8