1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// Copyright 2006-2008 the V8 project authors. All rights reserved. 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// Use of this source code is governed by a BSD-style license that can be 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// found in the LICENSE file. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// 5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#ifndef V8_HANDLES_INL_H_ 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#define V8_HANDLES_INL_H_ 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#include "src/api.h" 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#include "src/handles.h" 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#include "src/heap/heap.h" 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#include "src/isolate.h" 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratonamespace v8 { 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratonamespace internal { 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratotemplate<typename T> 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe OnoratoHandle<T>::Handle(T* obj) { 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato location_ = HandleScope::CreateHandle(obj->GetIsolate(), obj); 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratotemplate<typename T> 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe OnoratoHandle<T>::Handle(T* obj, Isolate* isolate) { 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato location_ = HandleScope::CreateHandle(isolate, obj); 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 27b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratotemplate <typename T> 30b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wanginline bool Handle<T>::is_identical_to(const Handle<T> o) const { 31b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Dereferencing deferred handles to check object equality is safe. 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato SLOW_DCHECK( 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (location_ == NULL || IsDereferenceAllowed(NO_DEFERRED_CHECK)) && 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (o.location_ == NULL || o.IsDereferenceAllowed(NO_DEFERRED_CHECK))); 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (location_ == o.location_) return true; 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (location_ == NULL || o.location_ == NULL) return false; 37b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return *location_ == *o.location_; 38b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 39b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 41b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangtemplate <typename T> 42b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wanginline T* Handle<T>::operator*() const { 43b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return *bit_cast<T**>(location_); 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratotemplate <typename T> 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoinline T** Handle<T>::location() const { 49b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang SLOW_DCHECK(location_ == NULL || 50b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); 51b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return location_; 52b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 53b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 54b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang#ifdef DEBUG 55b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangtemplate <typename T> 56b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangbool Handle<T>::IsDereferenceAllowed(DereferenceCheckMode mode) const { 57b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang DCHECK(location_ != NULL); 58b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Object* object = *bit_cast<T**>(location_); 59b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (object->IsSmi()) return true; 60b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang HeapObject* heap_object = HeapObject::cast(object); 61b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Heap* heap = heap_object->GetHeap(); 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Object** handle = reinterpret_cast<Object**>(location_); 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Object** roots_array_start = heap->roots_array_start(); 64b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (roots_array_start <= handle && 65b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang handle < roots_array_start + Heap::kStrongRootListLength && 66b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang heap->RootCanBeTreatedAsConstant( 67b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang static_cast<Heap::RootListIndex>(handle - roots_array_start))) { 68b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return true; 69b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 70b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (!AllowHandleDereference::IsAllowed()) return false; 71b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (mode == INCLUDE_DEFERRED_CHECK && 72b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang !AllowDeferredHandleDereference::IsAllowed()) { 73b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Accessing cells, maps and internalized strings is safe. 74b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (heap_object->IsCell()) return true; 75b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (heap_object->IsMap()) return true; 76b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (heap_object->IsInternalizedString()) return true; 77b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return !heap->isolate()->IsDeferredHandle(handle); 78b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 79b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return true; 80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang#endif 82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing WangHandleScope::HandleScope(Isolate* isolate) { 86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang HandleScopeData* current = isolate->handle_scope_data(); 87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang isolate_ = isolate; 88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang prev_next_ = current->next; 89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang prev_limit_ = current->limit; 90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang current->level++; 91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 94b9cc48a43ed984587c939d02fba5316bf5c0df6eYing WangHandleScope::~HandleScope() { 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato CloseScope(isolate_, prev_next_, prev_limit_); 96b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 98b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 99b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangvoid HandleScope::CloseScope(Isolate* isolate, 100b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Object** prev_next, 101b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Object** prev_limit) { 102b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang HandleScopeData* current = isolate->handle_scope_data(); 103b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato std::swap(current->next, prev_next); 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato current->level--; 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (current->limit != prev_limit) { 107b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang current->limit = prev_limit; 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato DeleteExtensions(isolate); 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#ifdef ENABLE_HANDLE_ZAPPING 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ZapRange(current->next, prev_limit); 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } else { 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ZapRange(current->next, prev_next); 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato#endif 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratotemplate <typename T> 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe OnoratoHandle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) { 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato HandleScopeData* current = isolate_->handle_scope_data(); 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato T* value = *handle_value; 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Throw away all handles in the current scope. 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato CloseScope(isolate_, prev_next_, prev_limit_); 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Allocate one handle in the parent scope. 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato DCHECK(current->level > 0); 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Handle<T> result(CreateHandle<T>(isolate_, value)); 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Reinitialize the current scope (so that it's ready 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // to be used or closed again). 130 prev_next_ = current->next; 131 prev_limit_ = current->limit; 132 current->level++; 133 return result; 134} 135 136 137template <typename T> 138T** HandleScope::CreateHandle(Isolate* isolate, T* value) { 139 DCHECK(AllowHandleAllocation::IsAllowed()); 140 HandleScopeData* current = isolate->handle_scope_data(); 141 142 internal::Object** cur = current->next; 143 if (cur == current->limit) cur = Extend(isolate); 144 // Update the current next field, set the value in the created 145 // handle, and return the result. 146 DCHECK(cur < current->limit); 147 current->next = cur + 1; 148 149 T** result = reinterpret_cast<T**>(cur); 150 *result = value; 151 return result; 152} 153 154 155#ifdef DEBUG 156inline SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) { 157 // Make sure the current thread is allowed to create handles to begin with. 158 CHECK(AllowHandleAllocation::IsAllowed()); 159 HandleScopeData* current = isolate_->handle_scope_data(); 160 // Shrink the current handle scope to make it impossible to do 161 // handle allocations without an explicit handle scope. 162 limit_ = current->limit; 163 current->limit = current->next; 164 level_ = current->level; 165 current->level = 0; 166} 167 168 169inline SealHandleScope::~SealHandleScope() { 170 // Restore state in current handle scope to re-enable handle 171 // allocations. 172 HandleScopeData* current = isolate_->handle_scope_data(); 173 DCHECK_EQ(0, current->level); 174 current->level = level_; 175 DCHECK_EQ(current->next, current->limit); 176 current->limit = limit_; 177} 178 179#endif 180 181} } // namespace v8::internal 182 183#endif // V8_HANDLES_INL_H_ 184