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/execution/simulator-base.h"
6
7 #include "src/execution/isolate.h"
8 #include "src/execution/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
InitializeOncePerProcess()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
GlobalTearDown()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
RedirectExternalReference(Address external_function,ExternalReference::Type type)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
Redirection(Address external_function,ExternalReference::Type type)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
Get(Address external_function,ExternalReference::Type type)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