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
12namespace v8 {
13namespace internal {
14
15// static
16base::Mutex* SimulatorBase::redirection_mutex_ = nullptr;
17
18// static
19Redirection* SimulatorBase::redirection_ = nullptr;
20
21// static
22base::Mutex* SimulatorBase::i_cache_mutex_ = nullptr;
23
24// static
25base::CustomMatcherHashMap* SimulatorBase::i_cache_ = nullptr;
26
27// static
28void 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
40void 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
61Address 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
68Redirection::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
87Redirection* 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