• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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