LCOV - code coverage report
Current view: top level - src - api.h (source / functions) Hit Total Coverage
Test: app.info Lines: 69 72 95.8 %
Date: 2017-10-20 Functions: 32 36 88.9 %

          Line data    Source code
       1             : // Copyright 2012 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_API_H_
       6             : #define V8_API_H_
       7             : 
       8             : #include "include/v8-testing.h"
       9             : #include "src/contexts.h"
      10             : #include "src/debug/debug-interface.h"
      11             : #include "src/detachable-vector.h"
      12             : #include "src/factory.h"
      13             : #include "src/isolate.h"
      14             : 
      15             : namespace v8 {
      16             : 
      17             : // Constants used in the implementation of the API.  The most natural thing
      18             : // would usually be to place these with the classes that use them, but
      19             : // we want to keep them out of v8.h because it is an externally
      20             : // visible file.
      21             : class Consts {
      22             :  public:
      23             :   enum TemplateType {
      24             :     FUNCTION_TEMPLATE = 0,
      25             :     OBJECT_TEMPLATE = 1
      26             :   };
      27             : };
      28             : 
      29     1462529 : template <typename T> inline T ToCData(v8::internal::Object* obj) {
      30             :   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
      31    17579135 :   if (obj == v8::internal::Smi::kZero) return nullptr;
      32             :   return reinterpret_cast<T>(
      33             :       reinterpret_cast<intptr_t>(
      34    17252824 :           v8::internal::Foreign::cast(obj)->foreign_address()));
      35             : }
      36             : 
      37             : 
      38             : template <typename T>
      39     3403504 : inline v8::internal::Handle<v8::internal::Object> FromCData(
      40             :     v8::internal::Isolate* isolate, T obj) {
      41             :   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
      42     3405210 :   if (obj == nullptr) return handle(v8::internal::Smi::kZero, isolate);
      43             :   return isolate->factory()->NewForeign(
      44     3401798 :       reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
      45             : }
      46             : 
      47             : 
      48             : class ApiFunction {
      49             :  public:
      50      169757 :   explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
      51      169757 :   v8::internal::Address address() { return addr_; }
      52             :  private:
      53             :   v8::internal::Address addr_;
      54             : };
      55             : 
      56             : 
      57             : 
      58             : class RegisteredExtension {
      59             :  public:
      60             :   explicit RegisteredExtension(Extension* extension);
      61             :   static void Register(RegisteredExtension* that);
      62             :   static void UnregisterAll();
      63             :   Extension* extension() { return extension_; }
      64             :   RegisteredExtension* next() { return next_; }
      65       87030 :   static RegisteredExtension* first_extension() { return first_extension_; }
      66             :  private:
      67             :   Extension* extension_;
      68             :   RegisteredExtension* next_;
      69             :   static RegisteredExtension* first_extension_;
      70             : };
      71             : 
      72             : #define OPEN_HANDLE_LIST(V)                    \
      73             :   V(Template, TemplateInfo)                    \
      74             :   V(FunctionTemplate, FunctionTemplateInfo)    \
      75             :   V(ObjectTemplate, ObjectTemplateInfo)        \
      76             :   V(Signature, FunctionTemplateInfo)           \
      77             :   V(AccessorSignature, FunctionTemplateInfo)   \
      78             :   V(Data, Object)                              \
      79             :   V(RegExp, JSRegExp)                          \
      80             :   V(Object, JSReceiver)                        \
      81             :   V(Array, JSArray)                            \
      82             :   V(Map, JSMap)                                \
      83             :   V(Set, JSSet)                                \
      84             :   V(ArrayBuffer, JSArrayBuffer)                \
      85             :   V(ArrayBufferView, JSArrayBufferView)        \
      86             :   V(TypedArray, JSTypedArray)                  \
      87             :   V(Uint8Array, JSTypedArray)                  \
      88             :   V(Uint8ClampedArray, JSTypedArray)           \
      89             :   V(Int8Array, JSTypedArray)                   \
      90             :   V(Uint16Array, JSTypedArray)                 \
      91             :   V(Int16Array, JSTypedArray)                  \
      92             :   V(Uint32Array, JSTypedArray)                 \
      93             :   V(Int32Array, JSTypedArray)                  \
      94             :   V(Float32Array, JSTypedArray)                \
      95             :   V(Float64Array, JSTypedArray)                \
      96             :   V(DataView, JSDataView)                      \
      97             :   V(SharedArrayBuffer, JSArrayBuffer)          \
      98             :   V(Name, Name)                                \
      99             :   V(String, String)                            \
     100             :   V(Symbol, Symbol)                            \
     101             :   V(Script, JSFunction)                        \
     102             :   V(UnboundScript, SharedFunctionInfo)         \
     103             :   V(Module, Module)                            \
     104             :   V(Function, JSReceiver)                      \
     105             :   V(Message, JSMessageObject)                  \
     106             :   V(Context, Context)                          \
     107             :   V(External, Object)                          \
     108             :   V(StackTrace, FixedArray)                    \
     109             :   V(StackFrame, StackFrameInfo)                \
     110             :   V(Proxy, JSProxy)                            \
     111             :   V(NativeWeakMap, JSWeakMap)                  \
     112             :   V(debug::GeneratorObject, JSGeneratorObject) \
     113             :   V(debug::Script, Script)                     \
     114             :   V(Promise, JSPromise)                        \
     115             :   V(Primitive, Object)                         \
     116             :   V(PrimitiveArray, FixedArray)                \
     117             :   V(ScriptOrModule, Script)
     118             : 
     119             : class Utils {
     120             :  public:
     121             :   static inline bool ApiCheck(bool condition,
     122             :                               const char* location,
     123             :                               const char* message) {
     124   697556079 :     if (!condition) Utils::ReportApiFailure(location, message);
     125             :     return condition;
     126             :   }
     127             :   static void ReportOOMFailure(const char* location, bool is_heap_oom);
     128             : 
     129             :   static inline Local<Context> ToLocal(
     130             :       v8::internal::Handle<v8::internal::Context> obj);
     131             :   static inline Local<Value> ToLocal(
     132             :       v8::internal::Handle<v8::internal::Object> obj);
     133             :   static inline Local<Module> ToLocal(
     134             :       v8::internal::Handle<v8::internal::Module> obj);
     135             :   static inline Local<Name> ToLocal(
     136             :       v8::internal::Handle<v8::internal::Name> obj);
     137             :   static inline Local<String> ToLocal(
     138             :       v8::internal::Handle<v8::internal::String> obj);
     139             :   static inline Local<Symbol> ToLocal(
     140             :       v8::internal::Handle<v8::internal::Symbol> obj);
     141             :   static inline Local<RegExp> ToLocal(
     142             :       v8::internal::Handle<v8::internal::JSRegExp> obj);
     143             :   static inline Local<Object> ToLocal(
     144             :       v8::internal::Handle<v8::internal::JSReceiver> obj);
     145             :   static inline Local<Object> ToLocal(
     146             :       v8::internal::Handle<v8::internal::JSObject> obj);
     147             :   static inline Local<Function> ToLocal(
     148             :       v8::internal::Handle<v8::internal::JSFunction> obj);
     149             :   static inline Local<Array> ToLocal(
     150             :       v8::internal::Handle<v8::internal::JSArray> obj);
     151             :   static inline Local<Map> ToLocal(
     152             :       v8::internal::Handle<v8::internal::JSMap> obj);
     153             :   static inline Local<Set> ToLocal(
     154             :       v8::internal::Handle<v8::internal::JSSet> obj);
     155             :   static inline Local<Proxy> ToLocal(
     156             :       v8::internal::Handle<v8::internal::JSProxy> obj);
     157             :   static inline Local<ArrayBuffer> ToLocal(
     158             :       v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
     159             :   static inline Local<ArrayBufferView> ToLocal(
     160             :       v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
     161             :   static inline Local<DataView> ToLocal(
     162             :       v8::internal::Handle<v8::internal::JSDataView> obj);
     163             :   static inline Local<TypedArray> ToLocal(
     164             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     165             :   static inline Local<Uint8Array> ToLocalUint8Array(
     166             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     167             :   static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
     168             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     169             :   static inline Local<Int8Array> ToLocalInt8Array(
     170             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     171             :   static inline Local<Uint16Array> ToLocalUint16Array(
     172             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     173             :   static inline Local<Int16Array> ToLocalInt16Array(
     174             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     175             :   static inline Local<Uint32Array> ToLocalUint32Array(
     176             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     177             :   static inline Local<Int32Array> ToLocalInt32Array(
     178             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     179             :   static inline Local<Float32Array> ToLocalFloat32Array(
     180             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     181             :   static inline Local<Float64Array> ToLocalFloat64Array(
     182             :       v8::internal::Handle<v8::internal::JSTypedArray> obj);
     183             : 
     184             :   static inline Local<SharedArrayBuffer> ToLocalShared(
     185             :       v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
     186             : 
     187             :   static inline Local<Message> MessageToLocal(
     188             :       v8::internal::Handle<v8::internal::Object> obj);
     189             :   static inline Local<Promise> PromiseToLocal(
     190             :       v8::internal::Handle<v8::internal::JSObject> obj);
     191             :   static inline Local<StackTrace> StackTraceToLocal(
     192             :       v8::internal::Handle<v8::internal::FixedArray> obj);
     193             :   static inline Local<StackFrame> StackFrameToLocal(
     194             :       v8::internal::Handle<v8::internal::StackFrameInfo> obj);
     195             :   static inline Local<Number> NumberToLocal(
     196             :       v8::internal::Handle<v8::internal::Object> obj);
     197             :   static inline Local<Integer> IntegerToLocal(
     198             :       v8::internal::Handle<v8::internal::Object> obj);
     199             :   static inline Local<Uint32> Uint32ToLocal(
     200             :       v8::internal::Handle<v8::internal::Object> obj);
     201             :   static inline Local<FunctionTemplate> ToLocal(
     202             :       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
     203             :   static inline Local<ObjectTemplate> ToLocal(
     204             :       v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
     205             :   static inline Local<Signature> SignatureToLocal(
     206             :       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
     207             :   static inline Local<AccessorSignature> AccessorSignatureToLocal(
     208             :       v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
     209             :   static inline Local<External> ExternalToLocal(
     210             :       v8::internal::Handle<v8::internal::JSObject> obj);
     211             :   static inline Local<NativeWeakMap> NativeWeakMapToLocal(
     212             :       v8::internal::Handle<v8::internal::JSWeakMap> obj);
     213             :   static inline Local<Function> CallableToLocal(
     214             :       v8::internal::Handle<v8::internal::JSReceiver> obj);
     215             :   static inline Local<Primitive> ToLocalPrimitive(
     216             :       v8::internal::Handle<v8::internal::Object> obj);
     217             :   static inline Local<PrimitiveArray> ToLocal(
     218             :       v8::internal::Handle<v8::internal::FixedArray> obj);
     219             :   static inline Local<ScriptOrModule> ScriptOrModuleToLocal(
     220             :       v8::internal::Handle<v8::internal::Script> obj);
     221             : 
     222             : #define DECLARE_OPEN_HANDLE(From, To) \
     223             :   static inline v8::internal::Handle<v8::internal::To> \
     224             :       OpenHandle(const From* that, bool allow_empty_handle = false);
     225             : 
     226             : OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
     227             : 
     228             : #undef DECLARE_OPEN_HANDLE
     229             : 
     230             :   template<class From, class To>
     231             :   static inline Local<To> Convert(v8::internal::Handle<From> obj) {
     232             :     DCHECK(obj.is_null() ||
     233             :            (obj->IsSmi() ||
     234             :             !obj->IsTheHole(i::HeapObject::cast(*obj)->GetIsolate())));
     235             :     return Local<To>(reinterpret_cast<To*>(obj.location()));
     236             :   }
     237             : 
     238             :   template <class T>
     239             :   static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
     240             :       const v8::Persistent<T>& persistent) {
     241             :     return v8::internal::Handle<v8::internal::Object>(
     242          15 :         reinterpret_cast<v8::internal::Object**>(persistent.val_));
     243             :   }
     244             : 
     245             :   template <class T>
     246             :   static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
     247             :       v8::Persistent<T>* persistent) {
     248             :     return OpenPersistent(*persistent);
     249             :   }
     250             : 
     251             :   template <class From, class To>
     252             :   static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
     253             :     return OpenHandle(*handle);
     254             :   }
     255             : 
     256             :  private:
     257             :   static void ReportApiFailure(const char* location, const char* message);
     258             : };
     259             : 
     260             : 
     261             : template <class T>
     262             : inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
     263             :   return reinterpret_cast<T*>(obj.location());
     264             : }
     265             : 
     266             : template <class T>
     267             : inline v8::Local<T> ToApiHandle(
     268             :     v8::internal::Handle<v8::internal::Object> obj) {
     269             :   return Utils::Convert<v8::internal::Object, T>(obj);
     270             : }
     271             : 
     272             : 
     273             : template <class T>
     274             : inline bool ToLocal(v8::internal::MaybeHandle<v8::internal::Object> maybe,
     275             :                     Local<T>* local) {
     276             :   v8::internal::Handle<v8::internal::Object> handle;
     277     1137618 :   if (maybe.ToHandle(&handle)) {
     278             :     *local = Utils::Convert<v8::internal::Object, T>(handle);
     279             :     return true;
     280             :   }
     281             :   return false;
     282             : }
     283             : 
     284             : 
     285             : // Implementations of ToLocal
     286             : 
     287             : #define MAKE_TO_LOCAL(Name, From, To)                                       \
     288             :   Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
     289             :     return Convert<v8::internal::From, v8::To>(obj);  \
     290             :   }
     291             : 
     292             : 
     293             : #define MAKE_TO_LOCAL_TYPED_ARRAY(Type, typeName, TYPE, ctype, size)  \
     294             :   Local<v8::Type##Array> Utils::ToLocal##Type##Array(                 \
     295             :       v8::internal::Handle<v8::internal::JSTypedArray> obj) {         \
     296             :     DCHECK(obj->type() == v8::internal::kExternal##Type##Array);      \
     297             :     return Convert<v8::internal::JSTypedArray, v8::Type##Array>(obj); \
     298             :   }
     299             : 
     300             : 
     301             : MAKE_TO_LOCAL(ToLocal, Context, Context)
     302             : MAKE_TO_LOCAL(ToLocal, Object, Value)
     303             : MAKE_TO_LOCAL(ToLocal, Module, Module)
     304             : MAKE_TO_LOCAL(ToLocal, Name, Name)
     305         961 : MAKE_TO_LOCAL(ToLocal, String, String)
     306             : MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
     307             : MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
     308             : MAKE_TO_LOCAL(ToLocal, JSReceiver, Object)
     309             : MAKE_TO_LOCAL(ToLocal, JSObject, Object)
     310             : MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
     311             : MAKE_TO_LOCAL(ToLocal, JSArray, Array)
     312             : MAKE_TO_LOCAL(ToLocal, JSMap, Map)
     313             : MAKE_TO_LOCAL(ToLocal, JSSet, Set)
     314             : MAKE_TO_LOCAL(ToLocal, JSProxy, Proxy)
     315             : MAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
     316             : MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
     317             : MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
     318             : MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
     319             : MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer)
     320             : 
     321             : TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY)
     322             : 
     323             : MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
     324             : MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
     325             : MAKE_TO_LOCAL(SignatureToLocal, FunctionTemplateInfo, Signature)
     326             : MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
     327             : MAKE_TO_LOCAL(MessageToLocal, Object, Message)
     328             : MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
     329             : MAKE_TO_LOCAL(StackTraceToLocal, FixedArray, StackTrace)
     330             : MAKE_TO_LOCAL(StackFrameToLocal, StackFrameInfo, StackFrame)
     331             : MAKE_TO_LOCAL(NumberToLocal, Object, Number)
     332             : MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
     333             : MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
     334             : MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
     335             : MAKE_TO_LOCAL(NativeWeakMapToLocal, JSWeakMap, NativeWeakMap)
     336             : MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function)
     337             : MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive)
     338             : MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray)
     339             : MAKE_TO_LOCAL(ScriptOrModuleToLocal, Script, ScriptOrModule)
     340             : 
     341             : #undef MAKE_TO_LOCAL_TYPED_ARRAY
     342             : #undef MAKE_TO_LOCAL
     343             : 
     344             : 
     345             : // Implementations of OpenHandle
     346             : 
     347             : #define MAKE_OPEN_HANDLE(From, To)                                             \
     348             :   v8::internal::Handle<v8::internal::To> Utils::OpenHandle(                    \
     349             :       const v8::From* that, bool allow_empty_handle) {                         \
     350             :     DCHECK(allow_empty_handle || that != nullptr);                             \
     351             :     DCHECK(that == nullptr ||                                                  \
     352             :            (*reinterpret_cast<v8::internal::Object* const*>(that))->Is##To()); \
     353             :     return v8::internal::Handle<v8::internal::To>(                             \
     354             :         reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that)));    \
     355             :   }
     356             : 
     357         140 : OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
     358             : 
     359             : #undef MAKE_OPEN_HANDLE
     360             : #undef OPEN_HANDLE_LIST
     361             : 
     362             : extern Isolate* IsolateNewImpl(internal::Isolate* isolate,
     363             :                                const Isolate::CreateParams& params);
     364             : 
     365             : namespace internal {
     366             : 
     367             : class V8_EXPORT_PRIVATE DeferredHandles {
     368             :  public:
     369             :   ~DeferredHandles();
     370             : 
     371             :  private:
     372             :   DeferredHandles(Object** first_block_limit, Isolate* isolate)
     373             :       : next_(nullptr),
     374             :         previous_(nullptr),
     375             :         first_block_limit_(first_block_limit),
     376        9393 :         isolate_(isolate) {
     377        9393 :     isolate->LinkDeferredHandles(this);
     378             :   }
     379             : 
     380             :   void Iterate(RootVisitor* v);
     381             : 
     382             :   std::vector<Object**> blocks_;
     383             :   DeferredHandles* next_;
     384             :   DeferredHandles* previous_;
     385             :   Object** first_block_limit_;
     386             :   Isolate* isolate_;
     387             : 
     388             :   friend class HandleScopeImplementer;
     389             :   friend class Isolate;
     390             : };
     391             : 
     392             : 
     393             : // This class is here in order to be able to declare it a friend of
     394             : // HandleScope.  Moving these methods to be members of HandleScope would be
     395             : // neat in some ways, but it would expose internal implementation details in
     396             : // our public header file, which is undesirable.
     397             : //
     398             : // An isolate has a single instance of this class to hold the current thread's
     399             : // data. In multithreaded V8 programs this data is copied in and out of storage
     400             : // so that the currently executing thread always has its own copy of this
     401             : // data.
     402             : class HandleScopeImplementer {
     403             :  public:
     404             :   explicit HandleScopeImplementer(Isolate* isolate)
     405             :       : isolate_(isolate),
     406             :         microtask_context_(nullptr),
     407             :         spare_(nullptr),
     408             :         call_depth_(0),
     409             :         microtasks_depth_(0),
     410             :         microtasks_suppressions_(0),
     411             :         entered_context_count_during_microtasks_(0),
     412             : #ifdef DEBUG
     413             :         debug_microtasks_depth_(0),
     414             : #endif
     415             :         microtasks_policy_(v8::MicrotasksPolicy::kAuto),
     416      109998 :         last_handle_before_deferred_block_(nullptr) {
     417             :   }
     418             : 
     419      106730 :   ~HandleScopeImplementer() {
     420       53365 :     DeleteArray(spare_);
     421       53365 :   }
     422             : 
     423             :   // Threading support for handle data.
     424             :   static int ArchiveSpacePerThread();
     425             :   char* RestoreThread(char* from);
     426             :   char* ArchiveThread(char* to);
     427             :   void FreeThreadResources();
     428             : 
     429             :   // Garbage collection support.
     430             :   void Iterate(v8::internal::RootVisitor* v);
     431             :   static char* Iterate(v8::internal::RootVisitor* v, char* data);
     432             : 
     433             :   inline internal::Object** GetSpareOrNewBlock();
     434             :   inline void DeleteExtensions(internal::Object** prev_limit);
     435             : 
     436             :   // Call depth represents nested v8 api calls.
     437   133775838 :   inline void IncrementCallDepth() {call_depth_++;}
     438   133775879 :   inline void DecrementCallDepth() {call_depth_--;}
     439       14118 :   inline bool CallDepthIsZero() { return call_depth_ == 0; }
     440             : 
     441             :   // Microtasks scope depth represents nested scopes controlling microtasks
     442             :   // invocation, which happens when depth reaches zero.
     443      130359 :   inline void IncrementMicrotasksScopeDepth() {microtasks_depth_++;}
     444      130360 :   inline void DecrementMicrotasksScopeDepth() {microtasks_depth_--;}
     445             :   inline int GetMicrotasksScopeDepth() { return microtasks_depth_; }
     446             : 
     447             :   // Possibly nested microtasks suppression scopes prevent microtasks
     448             :   // from running.
     449       98363 :   inline void IncrementMicrotasksSuppressions() {microtasks_suppressions_++;}
     450       98362 :   inline void DecrementMicrotasksSuppressions() {microtasks_suppressions_--;}
     451             :   inline bool HasMicrotasksSuppressions() { return !!microtasks_suppressions_; }
     452             : 
     453             : #ifdef DEBUG
     454             :   // In debug we check that calls not intended to invoke microtasks are
     455             :   // still correctly wrapped with microtask scopes.
     456             :   inline void IncrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_++;}
     457             :   inline void DecrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_--;}
     458             :   inline bool DebugMicrotasksScopeDepthIsZero() {
     459             :     return debug_microtasks_depth_ == 0;
     460             :   }
     461             : #endif
     462             : 
     463             :   inline void set_microtasks_policy(v8::MicrotasksPolicy policy);
     464             :   inline v8::MicrotasksPolicy microtasks_policy() const;
     465             : 
     466             :   inline void EnterContext(Handle<Context> context);
     467             :   inline void LeaveContext();
     468             :   inline bool LastEnteredContextWas(Handle<Context> context);
     469             : 
     470             :   // Returns the last entered context or an empty handle if no
     471             :   // contexts have been entered.
     472             :   inline Handle<Context> LastEnteredContext();
     473             : 
     474             :   inline void EnterMicrotaskContext(Handle<Context> context);
     475             :   inline void LeaveMicrotaskContext();
     476             :   inline Handle<Context> MicrotaskContext();
     477             :   inline bool MicrotaskContextIsLastEnteredContext() const {
     478     1198467 :     return microtask_context_ &&
     479           0 :            entered_context_count_during_microtasks_ == entered_contexts_.size();
     480             :   }
     481             : 
     482             :   inline void SaveContext(Context* context);
     483             :   inline Context* RestoreContext();
     484             :   inline bool HasSavedContexts();
     485             : 
     486             :   inline DetachableVector<Object**>* blocks() { return &blocks_; }
     487             :   Isolate* isolate() const { return isolate_; }
     488             : 
     489             :   void ReturnBlock(Object** block) {
     490             :     DCHECK_NOT_NULL(block);
     491        9390 :     if (spare_ != nullptr) DeleteArray(spare_);
     492        9390 :     spare_ = block;
     493             :   }
     494             : 
     495             :  private:
     496             :   void ResetAfterArchive() {
     497             :     blocks_.detach();
     498             :     entered_contexts_.detach();
     499             :     saved_contexts_.detach();
     500       24163 :     microtask_context_ = nullptr;
     501       24163 :     entered_context_count_during_microtasks_ = 0;
     502       24163 :     spare_ = nullptr;
     503       24163 :     last_handle_before_deferred_block_ = nullptr;
     504       24163 :     call_depth_ = 0;
     505             :   }
     506             : 
     507        5856 :   void Free() {
     508             :     DCHECK(blocks_.empty());
     509             :     DCHECK(entered_contexts_.empty());
     510             :     DCHECK(saved_contexts_.empty());
     511             :     DCHECK(!microtask_context_);
     512             : 
     513        5856 :     blocks_.free();
     514        5856 :     entered_contexts_.free();
     515        5856 :     saved_contexts_.free();
     516        5856 :     if (spare_ != nullptr) {
     517             :       DeleteArray(spare_);
     518        5788 :       spare_ = nullptr;
     519             :     }
     520             :     DCHECK_EQ(call_depth_, 0);
     521        5856 :   }
     522             : 
     523             :   void BeginDeferredScope();
     524             :   DeferredHandles* Detach(Object** prev_limit);
     525             : 
     526             :   Isolate* isolate_;
     527             :   DetachableVector<Object**> blocks_;
     528             :   // Used as a stack to keep track of entered contexts.
     529             :   DetachableVector<Context*> entered_contexts_;
     530             :   // Used as a stack to keep track of saved contexts.
     531             :   DetachableVector<Context*> saved_contexts_;
     532             :   Context* microtask_context_;
     533             :   Object** spare_;
     534             :   int call_depth_;
     535             :   int microtasks_depth_;
     536             :   int microtasks_suppressions_;
     537             :   size_t entered_context_count_during_microtasks_;
     538             : #ifdef DEBUG
     539             :   int debug_microtasks_depth_;
     540             : #endif
     541             :   v8::MicrotasksPolicy microtasks_policy_;
     542             :   Object** last_handle_before_deferred_block_;
     543             :   // This is only used for threading support.
     544             :   HandleScopeData handle_scope_data_;
     545             : 
     546             :   void IterateThis(RootVisitor* v);
     547             :   char* RestoreThreadHelper(char* from);
     548             :   char* ArchiveThreadHelper(char* to);
     549             : 
     550             :   friend class DeferredHandles;
     551             :   friend class DeferredHandleScope;
     552             : 
     553             :   DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
     554             : };
     555             : 
     556             : 
     557             : const int kHandleBlockSize = v8::internal::KB - 2;  // fit in one page
     558             : 
     559             : 
     560             : void HandleScopeImplementer::set_microtasks_policy(
     561             :     v8::MicrotasksPolicy policy) {
     562        1657 :   microtasks_policy_ = policy;
     563             : }
     564             : 
     565             : 
     566             : v8::MicrotasksPolicy HandleScopeImplementer::microtasks_policy() const {
     567             :   return microtasks_policy_;
     568             : }
     569             : 
     570             : 
     571             : void HandleScopeImplementer::SaveContext(Context* context) {
     572    12765882 :   saved_contexts_.push_back(context);
     573             : }
     574             : 
     575             : 
     576             : Context* HandleScopeImplementer::RestoreContext() {
     577    12750894 :   Context* last_context = saved_contexts_.back();
     578             :   saved_contexts_.pop_back();
     579             :   return last_context;
     580             : }
     581             : 
     582             : 
     583             : bool HandleScopeImplementer::HasSavedContexts() {
     584             :   return !saved_contexts_.empty();
     585             : }
     586             : 
     587             : 
     588     1202125 : void HandleScopeImplementer::EnterContext(Handle<Context> context) {
     589     2404308 :   entered_contexts_.push_back(*context);
     590     1202183 : }
     591             : 
     592             : void HandleScopeImplementer::LeaveContext() { entered_contexts_.pop_back(); }
     593             : 
     594             : bool HandleScopeImplementer::LastEnteredContextWas(Handle<Context> context) {
     595     3561575 :   return !entered_contexts_.empty() && entered_contexts_.back() == *context;
     596             : }
     597             : 
     598             : 
     599     1244148 : Handle<Context> HandleScopeImplementer::LastEnteredContext() {
     600     1244148 :   if (entered_contexts_.empty()) return Handle<Context>::null();
     601     2488276 :   return Handle<Context>(entered_contexts_.back());
     602             : }
     603             : 
     604             : void HandleScopeImplementer::EnterMicrotaskContext(Handle<Context> context) {
     605             :   DCHECK(!microtask_context_);
     606      201613 :   microtask_context_ = *context;
     607      201613 :   entered_context_count_during_microtasks_ = entered_contexts_.size();
     608             : }
     609             : 
     610             : void HandleScopeImplementer::LeaveMicrotaskContext() {
     611             :   DCHECK(microtask_context_);
     612      201614 :   microtask_context_ = nullptr;
     613      201614 :   entered_context_count_during_microtasks_ = 0;
     614             : }
     615             : 
     616           0 : Handle<Context> HandleScopeImplementer::MicrotaskContext() {
     617           0 :   if (microtask_context_) return Handle<Context>(microtask_context_);
     618             :   return Handle<Context>::null();
     619             : }
     620             : 
     621             : // If there's a spare block, use it for growing the current scope.
     622             : internal::Object** HandleScopeImplementer::GetSpareOrNewBlock() {
     623             :   internal::Object** block =
     624     1390809 :       (spare_ != nullptr) ? spare_
     625     1390809 :                           : NewArray<internal::Object*>(kHandleBlockSize);
     626     1390809 :   spare_ = nullptr;
     627             :   return block;
     628             : }
     629             : 
     630             : 
     631     1161706 : void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
     632     3704824 :   while (!blocks_.empty()) {
     633     1826988 :     internal::Object** block_start = blocks_.back();
     634     1826988 :     internal::Object** block_limit = block_start + kHandleBlockSize;
     635             : 
     636             :     // SealHandleScope may make the prev_limit to point inside the block.
     637     1826988 :     if (block_start <= prev_limit && prev_limit <= block_limit) {
     638             : #ifdef ENABLE_HANDLE_ZAPPING
     639             :       internal::HandleScope::ZapRange(prev_limit, block_limit);
     640             : #endif
     641             :       break;
     642             :     }
     643             : 
     644             :     blocks_.pop_back();
     645             : #ifdef ENABLE_HANDLE_ZAPPING
     646             :     internal::HandleScope::ZapRange(block_start, block_limit);
     647             : #endif
     648     1381411 :     if (spare_ != nullptr) {
     649             :       DeleteArray(spare_);
     650             :     }
     651     1381412 :     spare_ = block_start;
     652             :   }
     653             :   DCHECK((blocks_.empty() && prev_limit == nullptr) ||
     654             :          (!blocks_.empty() && prev_limit != nullptr));
     655     1161707 : }
     656             : 
     657             : // Interceptor functions called from generated inline caches to notify
     658             : // CPU profiler that external callbacks are invoked.
     659             : void InvokeAccessorGetterCallback(
     660             :     v8::Local<v8::Name> property,
     661             :     const v8::PropertyCallbackInfo<v8::Value>& info,
     662             :     v8::AccessorNameGetterCallback getter);
     663             : 
     664             : void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
     665             :                             v8::FunctionCallback callback);
     666             : 
     667             : class Testing {
     668             :  public:
     669       22006 :   static v8::Testing::StressType stress_type() { return stress_type_; }
     670             :   static void set_stress_type(v8::Testing::StressType stress_type) {
     671        4402 :     stress_type_ = stress_type;
     672             :   }
     673             : 
     674             :  private:
     675             :   static v8::Testing::StressType stress_type_;
     676             : };
     677             : 
     678             : }  // namespace internal
     679             : }  // namespace v8
     680             : 
     681             : #endif  // V8_API_H_

Generated by: LCOV version 1.10