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
11 namespace v8 {
12 namespace internal {
13
RegisterNewlyAllocatedCodeObject(Address code)14 void 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
RegisterAlreadyExistingCodeObject(Address code)23 void 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
Clear()31 void 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
Finalize()38 void 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
Contains(Address object) const45 bool 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
GetCodeObjectStartFromInnerAddress(Address address) const55 Address 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