1 // Copyright 2020 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 #ifndef V8_EXECUTION_OFF_THREAD_ISOLATE_H_
6 #define V8_EXECUTION_OFF_THREAD_ISOLATE_H_
7 
8 #include "src/base/logging.h"
9 #include "src/execution/thread-id.h"
10 #include "src/handles/handles.h"
11 #include "src/heap/off-thread-factory.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 class Isolate;
17 class OffThreadLogger;
18 
19 // HiddenOffThreadFactory parallels Isolate's HiddenFactory
20 class V8_EXPORT_PRIVATE HiddenOffThreadFactory : private OffThreadFactory {
21  public:
22   // Forward constructors.
23   using OffThreadFactory::OffThreadFactory;
24 };
25 
26 // And Isolate-like class that can be passed in to templated methods that need
27 // an isolate syntactically, but are usable off-thread.
28 //
29 // This class holds an OffThreadFactory, but is otherwise effectively a stub
30 // implementation of an Isolate. In particular, it doesn't allow throwing
31 // exceptions, and hard crashes if you try.
32 class V8_EXPORT_PRIVATE OffThreadIsolate final
33     : private HiddenOffThreadFactory {
34  public:
35   using HandleScopeType = OffThreadHandleScope;
36 
37   explicit OffThreadIsolate(Isolate* isolate, Zone* zone);
38   ~OffThreadIsolate();
39 
factory()40   v8::internal::OffThreadFactory* factory() {
41     // Upcast to the privately inherited base-class using c-style casts to avoid
42     // undefined behavior (as static_cast cannot cast across private bases).
43     // NOLINTNEXTLINE (google-readability-casting)
44     return (
45         v8::internal::OffThreadFactory*)this;  // NOLINT(readability/casting)
46   }
47 
48   // This method finishes the use of the off-thread Isolate, and can be safely
49   // called off-thread.
FinishOffThread()50   void FinishOffThread() {
51     factory()->FinishOffThread();
52     handle_zone_ = nullptr;
53   }
54 
55   template <typename T>
Throw(Handle<Object> exception)56   Handle<T> Throw(Handle<Object> exception) {
57     UNREACHABLE();
58   }
FatalProcessOutOfHeapMemory(const char * location)59   [[noreturn]] void FatalProcessOutOfHeapMemory(const char* location) {
60     UNREACHABLE();
61   }
62 
NewHandle(Address object)63   Address* NewHandle(Address object) {
64     DCHECK_NOT_NULL(handle_zone_);
65     Address* location =
66         static_cast<Address*>(handle_zone_->New(sizeof(Address)));
67     *location = object;
68     return location;
69   }
70 
71   int GetNextScriptId();
72 #if V8_SFI_HAS_UNIQUE_ID
73   int GetNextUniqueSharedFunctionInfoId();
74 #endif  // V8_SFI_HAS_UNIQUE_ID
75 
76   bool NeedsSourcePositionsForProfiling();
77   bool is_collecting_type_profile();
78 
logger()79   OffThreadLogger* logger() { return logger_; }
80 
81   void PinToCurrentThread();
thread_id()82   ThreadId thread_id() { return thread_id_; }
83 
84  private:
85   friend class v8::internal::OffThreadFactory;
86 
87   // TODO(leszeks): Extract out the fields of the Isolate we want and store
88   // those instead of the whole thing.
89   Isolate* isolate_;
90 
91   OffThreadLogger* logger_;
92   ThreadId thread_id_;
93   Zone* handle_zone_;
94 };
95 
96 }  // namespace internal
97 }  // namespace v8
98 
99 #endif  // V8_EXECUTION_OFF_THREAD_ISOLATE_H_
100