V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
cpu-arm64.cc
1 // Copyright 2013 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 // CPU specific code for arm independent of OS goes here.
6 
7 #if V8_TARGET_ARCH_ARM64
8 
9 #include "src/arm64/utils-arm64.h"
10 #include "src/assembler.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class CacheLineSizes {
16  public:
17  CacheLineSizes() {
18 #if defined(USE_SIMULATOR) || defined(V8_OS_WIN)
19  cache_type_register_ = 0;
20 #else
21  // Copy the content of the cache type register to a core register.
22  __asm__ __volatile__("mrs %x[ctr], ctr_el0" // NOLINT
23  : [ctr] "=r"(cache_type_register_));
24 #endif
25  }
26 
27  uint32_t icache_line_size() const { return ExtractCacheLineSize(0); }
28  uint32_t dcache_line_size() const { return ExtractCacheLineSize(16); }
29 
30  private:
31  uint32_t ExtractCacheLineSize(int cache_line_size_shift) const {
32  // The cache type register holds the size of cache lines in words as a
33  // power of two.
34  return 4 << ((cache_type_register_ >> cache_line_size_shift) & 0xF);
35  }
36 
37  uint32_t cache_type_register_;
38 };
39 
40 void CpuFeatures::FlushICache(void* address, size_t length) {
41 #if defined(V8_OS_WIN)
42  FlushInstructionCache(GetCurrentProcess(), address, length);
43 #elif defined(V8_HOST_ARCH_ARM64)
44  // The code below assumes user space cache operations are allowed. The goal
45  // of this routine is to make sure the code generated is visible to the I
46  // side of the CPU.
47 
48  uintptr_t start = reinterpret_cast<uintptr_t>(address);
49  // Sizes will be used to generate a mask big enough to cover a pointer.
50  CacheLineSizes sizes;
51  uintptr_t dsize = sizes.dcache_line_size();
52  uintptr_t isize = sizes.icache_line_size();
53  // Cache line sizes are always a power of 2.
54  DCHECK_EQ(CountSetBits(dsize, 64), 1);
55  DCHECK_EQ(CountSetBits(isize, 64), 1);
56  uintptr_t dstart = start & ~(dsize - 1);
57  uintptr_t istart = start & ~(isize - 1);
58  uintptr_t end = start + length;
59 
60  __asm__ __volatile__ ( // NOLINT
61  // Clean every line of the D cache containing the target data.
62  "0: \n\t"
63  // dc : Data Cache maintenance
64  // c : Clean
65  // i : Invalidate
66  // va : by (Virtual) Address
67  // c : to the point of Coherency
68  // See ARM DDI 0406B page B2-12 for more information.
69  // We would prefer to use "cvau" (clean to the point of unification) here
70  // but we use "civac" to work around Cortex-A53 errata 819472, 826319,
71  // 827319 and 824069.
72  "dc civac, %[dline] \n\t"
73  "add %[dline], %[dline], %[dsize] \n\t"
74  "cmp %[dline], %[end] \n\t"
75  "b.lt 0b \n\t"
76  // Barrier to make sure the effect of the code above is visible to the rest
77  // of the world.
78  // dsb : Data Synchronisation Barrier
79  // ish : Inner SHareable domain
80  // The point of unification for an Inner Shareable shareability domain is
81  // the point by which the instruction and data caches of all the processors
82  // in that Inner Shareable shareability domain are guaranteed to see the
83  // same copy of a memory location. See ARM DDI 0406B page B2-12 for more
84  // information.
85  "dsb ish \n\t"
86  // Invalidate every line of the I cache containing the target data.
87  "1: \n\t"
88  // ic : instruction cache maintenance
89  // i : invalidate
90  // va : by address
91  // u : to the point of unification
92  "ic ivau, %[iline] \n\t"
93  "add %[iline], %[iline], %[isize] \n\t"
94  "cmp %[iline], %[end] \n\t"
95  "b.lt 1b \n\t"
96  // Barrier to make sure the effect of the code above is visible to the rest
97  // of the world.
98  "dsb ish \n\t"
99  // Barrier to ensure any prefetching which happened before this code is
100  // discarded.
101  // isb : Instruction Synchronisation Barrier
102  "isb \n\t"
103  : [dline] "+r" (dstart),
104  [iline] "+r" (istart)
105  : [dsize] "r" (dsize),
106  [isize] "r" (isize),
107  [end] "r" (end)
108  // This code does not write to memory but without the dependency gcc might
109  // move this code before the code is generated.
110  : "cc", "memory"
111  ); // NOLINT
112 #endif // V8_HOST_ARCH_ARM64
113 }
114 
115 } // namespace internal
116 } // namespace v8
117 
118 #endif // V8_TARGET_ARCH_ARM64
Definition: libplatform.h:13