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