1 | // Copyright 2017 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/simulator-base.h" |
6 | |
7 | #include "src/isolate.h" |
8 | #include "src/simulator.h" |
9 | |
10 | #if defined(USE_SIMULATOR) |
11 | |
12 | namespace v8 { |
13 | namespace internal { |
14 | |
15 | // static |
16 | base::Mutex* SimulatorBase::redirection_mutex_ = nullptr; |
17 | |
18 | // static |
19 | Redirection* SimulatorBase::redirection_ = nullptr; |
20 | |
21 | // static |
22 | base::Mutex* SimulatorBase::i_cache_mutex_ = nullptr; |
23 | |
24 | // static |
25 | base::CustomMatcherHashMap* SimulatorBase::i_cache_ = nullptr; |
26 | |
27 | // static |
28 | void SimulatorBase::InitializeOncePerProcess() { |
29 | DCHECK_NULL(redirection_mutex_); |
30 | redirection_mutex_ = new base::Mutex(); |
31 | |
32 | DCHECK_NULL(i_cache_mutex_); |
33 | i_cache_mutex_ = new base::Mutex(); |
34 | |
35 | DCHECK_NULL(i_cache_); |
36 | i_cache_ = new base::CustomMatcherHashMap(&Simulator::ICacheMatch); |
37 | } |
38 | |
39 | // static |
40 | void SimulatorBase::GlobalTearDown() { |
41 | delete redirection_mutex_; |
42 | redirection_mutex_ = nullptr; |
43 | |
44 | Redirection::DeleteChain(redirection_); |
45 | redirection_ = nullptr; |
46 | |
47 | delete i_cache_mutex_; |
48 | i_cache_mutex_ = nullptr; |
49 | |
50 | if (i_cache_ != nullptr) { |
51 | for (base::HashMap::Entry* entry = i_cache_->Start(); entry != nullptr; |
52 | entry = i_cache_->Next(entry)) { |
53 | delete static_cast<CachePage*>(entry->value); |
54 | } |
55 | } |
56 | delete i_cache_; |
57 | i_cache_ = nullptr; |
58 | } |
59 | |
60 | // static |
61 | Address SimulatorBase::RedirectExternalReference(Address external_function, |
62 | ExternalReference::Type type) { |
63 | base::MutexGuard lock_guard(Simulator::redirection_mutex()); |
64 | Redirection* redirection = Redirection::Get(external_function, type); |
65 | return redirection->address_of_instruction(); |
66 | } |
67 | |
68 | Redirection::Redirection(Address external_function, |
69 | ExternalReference::Type type) |
70 | : external_function_(external_function), type_(type), next_(nullptr) { |
71 | next_ = Simulator::redirection(); |
72 | base::MutexGuard lock_guard(Simulator::i_cache_mutex()); |
73 | Simulator::SetRedirectInstruction( |
74 | reinterpret_cast<Instruction*>(address_of_instruction())); |
75 | Simulator::FlushICache(Simulator::i_cache(), |
76 | reinterpret_cast<void*>(&instruction_), |
77 | sizeof(instruction_)); |
78 | Simulator::set_redirection(this); |
79 | #if ABI_USES_FUNCTION_DESCRIPTORS |
80 | function_descriptor_[0] = reinterpret_cast<intptr_t>(&instruction_); |
81 | function_descriptor_[1] = 0; |
82 | function_descriptor_[2] = 0; |
83 | #endif |
84 | } |
85 | |
86 | // static |
87 | Redirection* Redirection::Get(Address external_function, |
88 | ExternalReference::Type type) { |
89 | Redirection* current = Simulator::redirection(); |
90 | for (; current != nullptr; current = current->next_) { |
91 | if (current->external_function_ == external_function && |
92 | current->type_ == type) { |
93 | return current; |
94 | } |
95 | } |
96 | return new Redirection(external_function, type); |
97 | } |
98 | |
99 | } // namespace internal |
100 | } // namespace v8 |
101 | |
102 | #endif // defined(USE_SIMULATOR) |
103 | |