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 #include "src/v8.h" 6 7 #include "src/handles.h" 8 9 namespace v8 { 10 namespace internal { 11 12 NumberOfHandles(Isolate * isolate)13int HandleScope::NumberOfHandles(Isolate* isolate) { 14 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 15 int n = impl->blocks()->length(); 16 if (n == 0) return 0; 17 return ((n - 1) * kHandleBlockSize) + static_cast<int>( 18 (isolate->handle_scope_data()->next - impl->blocks()->last())); 19 } 20 21 Extend(Isolate * isolate)22Object** HandleScope::Extend(Isolate* isolate) { 23 HandleScopeData* current = isolate->handle_scope_data(); 24 25 Object** result = current->next; 26 27 DCHECK(result == current->limit); 28 // Make sure there's at least one scope on the stack and that the 29 // top of the scope stack isn't a barrier. 30 if (!Utils::ApiCheck(current->level != 0, 31 "v8::HandleScope::CreateHandle()", 32 "Cannot create a handle without a HandleScope")) { 33 return NULL; 34 } 35 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 36 // If there's more room in the last block, we use that. This is used 37 // for fast creation of scopes after scope barriers. 38 if (!impl->blocks()->is_empty()) { 39 Object** limit = &impl->blocks()->last()[kHandleBlockSize]; 40 if (current->limit != limit) { 41 current->limit = limit; 42 DCHECK(limit - current->next < kHandleBlockSize); 43 } 44 } 45 46 // If we still haven't found a slot for the handle, we extend the 47 // current handle scope by allocating a new handle block. 48 if (result == current->limit) { 49 // If there's a spare block, use it for growing the current scope. 50 result = impl->GetSpareOrNewBlock(); 51 // Add the extension to the global list of blocks, but count the 52 // extension as part of the current scope. 53 impl->blocks()->Add(result); 54 current->limit = &result[kHandleBlockSize]; 55 } 56 57 return result; 58 } 59 60 DeleteExtensions(Isolate * isolate)61void HandleScope::DeleteExtensions(Isolate* isolate) { 62 HandleScopeData* current = isolate->handle_scope_data(); 63 isolate->handle_scope_implementer()->DeleteExtensions(current->limit); 64 } 65 66 67 #ifdef ENABLE_HANDLE_ZAPPING ZapRange(Object ** start,Object ** end)68void HandleScope::ZapRange(Object** start, Object** end) { 69 DCHECK(end - start <= kHandleBlockSize); 70 for (Object** p = start; p != end; p++) { 71 *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue; 72 } 73 } 74 #endif 75 76 current_level_address(Isolate * isolate)77Address HandleScope::current_level_address(Isolate* isolate) { 78 return reinterpret_cast<Address>(&isolate->handle_scope_data()->level); 79 } 80 81 current_next_address(Isolate * isolate)82Address HandleScope::current_next_address(Isolate* isolate) { 83 return reinterpret_cast<Address>(&isolate->handle_scope_data()->next); 84 } 85 86 current_limit_address(Isolate * isolate)87Address HandleScope::current_limit_address(Isolate* isolate) { 88 return reinterpret_cast<Address>(&isolate->handle_scope_data()->limit); 89 } 90 91 DeferredHandleScope(Isolate * isolate)92DeferredHandleScope::DeferredHandleScope(Isolate* isolate) 93 : impl_(isolate->handle_scope_implementer()) { 94 impl_->BeginDeferredScope(); 95 HandleScopeData* data = impl_->isolate()->handle_scope_data(); 96 Object** new_next = impl_->GetSpareOrNewBlock(); 97 Object** new_limit = &new_next[kHandleBlockSize]; 98 DCHECK(data->limit == &impl_->blocks()->last()[kHandleBlockSize]); 99 impl_->blocks()->Add(new_next); 100 101 #ifdef DEBUG 102 prev_level_ = data->level; 103 #endif 104 data->level++; 105 prev_limit_ = data->limit; 106 prev_next_ = data->next; 107 data->next = new_next; 108 data->limit = new_limit; 109 } 110 111 ~DeferredHandleScope()112DeferredHandleScope::~DeferredHandleScope() { 113 impl_->isolate()->handle_scope_data()->level--; 114 DCHECK(handles_detached_); 115 DCHECK(impl_->isolate()->handle_scope_data()->level == prev_level_); 116 } 117 118 Detach()119DeferredHandles* DeferredHandleScope::Detach() { 120 DeferredHandles* deferred = impl_->Detach(prev_limit_); 121 HandleScopeData* data = impl_->isolate()->handle_scope_data(); 122 data->next = prev_next_; 123 data->limit = prev_limit_; 124 #ifdef DEBUG 125 handles_detached_ = true; 126 #endif 127 return deferred; 128 } 129 130 } } // namespace v8::internal 131