local-isolate-wrapper.h 2.95 KB
Newer Older
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_