summaryrefslogtreecommitdiff
path: root/chromium/v8/src/execution/local-isolate-wrapper.h
blob: 8dbf0c239193aeaf19a2e7762e3a7525d0857761 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_EXECUTION_LOCAL_ISOLATE_WRAPPER_H_
#define V8_EXECUTION_LOCAL_ISOLATE_WRAPPER_H_

#include "src/utils/pointer-with-payload.h"

namespace v8 {
namespace internal {

// LocalWrapperBase is the base-class for wrapper classes around a main-thread
// and off-thread type, e.g. Isolate and OffThreadIsolate, and a bit stating
// which of the two the wrapper wraps.
//
// The shared methods are defined on MethodCaller, which will dispatch to the
// right type depending on the state of the wrapper. The reason for a separate
// MethodCaller is to
//
//   a) Move the method definitions into an -inl.h so that this header can have
//      minimal dependencies, and
//   b) To allow the type methods to be called with operator-> (e.g.
//      isolate_wrapper->heap()), while forcing the wrapper methods to be called
//      with a dot (e.g. isolate_wrapper.is_main_thread()).
template <typename MainThreadType, typename OffThreadType,
          typename MethodCaller>
class LocalWrapperBase {
 public:
  // Helper for returning a MethodCaller* by value from operator->.
  class MethodCallerRef {
   public:
    MethodCaller* operator->() { return &caller_; }

   private:
    friend class LocalWrapperBase;
    explicit MethodCallerRef(LocalWrapperBase* wrapper) : caller_(wrapper) {}

    MethodCaller caller_;
  };

  explicit LocalWrapperBase(std::nullptr_t) : pointer_and_tag_(nullptr) {}
  explicit LocalWrapperBase(MainThreadType* pointer)
      : pointer_and_tag_(pointer, false) {}
  explicit LocalWrapperBase(OffThreadType* pointer)
      : pointer_and_tag_(pointer, true) {}

  MainThreadType* main_thread() {
    DCHECK(is_main_thread());
    return static_cast<MainThreadType*>(
        pointer_and_tag_.GetPointerWithKnownPayload(false));
  }
  OffThreadType* off_thread() {
    DCHECK(is_off_thread());
    return static_cast<OffThreadType*>(
        pointer_and_tag_.GetPointerWithKnownPayload(true));
  }

  bool is_main_thread() const {
    return !is_null() && !pointer_and_tag_.GetPayload();
  }
  bool is_off_thread() const {
    return !is_null() && pointer_and_tag_.GetPayload();
  }
  bool is_null() const { return pointer_and_tag_.GetPointer() == nullptr; }

  // Access the methods via wrapper->Method.
  MethodCallerRef operator->() { return MethodCallerRef(this); }

 private:
  PointerWithPayload<void, bool, 1> pointer_and_tag_;
};

using LocalHeapWrapper =
    LocalWrapperBase<class Heap, class OffThreadHeap, class HeapMethodCaller>;
using LocalLoggerWrapper = LocalWrapperBase<class Logger, class OffThreadLogger,
                                            class LoggerMethodCaller>;
using LocalIsolateWrapper =
    LocalWrapperBase<class Isolate, class OffThreadIsolate,
                     class IsolateMethodCaller>;

}  // namespace internal
}  // namespace v8

#endif  // V8_EXECUTION_LOCAL_ISOLATE_WRAPPER_H_