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