Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 1 | // Copyright 2006-2008 the V8 project authors. All rights reserved. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 4 | |
| 5 | #ifndef V8_HANDLES_INL_H_ |
| 6 | #define V8_HANDLES_INL_H_ |
| 7 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 8 | #include "src/api.h" |
| 9 | #include "src/handles.h" |
| 10 | #include "src/heap/heap.h" |
| 11 | #include "src/isolate.h" |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 12 | |
| 13 | namespace v8 { |
| 14 | namespace internal { |
| 15 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 16 | HandleBase::HandleBase(Object* object, Isolate* isolate) |
| 17 | : location_(HandleScope::GetHandle(isolate, object)) {} |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 18 | |
| 19 | |
| 20 | template <typename T> |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 21 | // Allocate a new handle for the object, do not canonicalize. |
| 22 | Handle<T> Handle<T>::New(T* object, Isolate* isolate) { |
| 23 | return Handle( |
| 24 | reinterpret_cast<T**>(HandleScope::CreateHandle(isolate, object))); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 28 | HandleScope::HandleScope(Isolate* isolate) { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 29 | HandleScopeData* data = isolate->handle_scope_data(); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 30 | isolate_ = isolate; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 31 | prev_next_ = data->next; |
| 32 | prev_limit_ = data->limit; |
| 33 | data->level++; |
| 34 | } |
| 35 | |
| 36 | |
| 37 | template <typename T> |
| 38 | inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) { |
| 39 | return os << Brief(*handle); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | |
| 43 | HandleScope::~HandleScope() { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 44 | #ifdef DEBUG |
| 45 | if (FLAG_check_handle_count) { |
| 46 | int before = NumberOfHandles(isolate_); |
| 47 | CloseScope(isolate_, prev_next_, prev_limit_); |
| 48 | int after = NumberOfHandles(isolate_); |
| 49 | DCHECK(after - before < kCheckHandleThreshold); |
| 50 | DCHECK(before < kCheckHandleThreshold); |
| 51 | } else { |
| 52 | #endif // DEBUG |
| 53 | CloseScope(isolate_, prev_next_, prev_limit_); |
| 54 | #ifdef DEBUG |
| 55 | } |
| 56 | #endif // DEBUG |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 57 | } |
| 58 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 59 | |
| 60 | void HandleScope::CloseScope(Isolate* isolate, |
| 61 | Object** prev_next, |
| 62 | Object** prev_limit) { |
| 63 | HandleScopeData* current = isolate->handle_scope_data(); |
| 64 | |
| 65 | std::swap(current->next, prev_next); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 66 | current->level--; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 67 | if (current->limit != prev_limit) { |
| 68 | current->limit = prev_limit; |
| 69 | DeleteExtensions(isolate); |
| 70 | #ifdef ENABLE_HANDLE_ZAPPING |
| 71 | ZapRange(current->next, prev_limit); |
| 72 | } else { |
| 73 | ZapRange(current->next, prev_next); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 74 | #endif |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 75 | } |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | |
| 79 | template <typename T> |
| 80 | Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 81 | HandleScopeData* current = isolate_->handle_scope_data(); |
| 82 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 83 | T* value = *handle_value; |
| 84 | // Throw away all handles in the current scope. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 85 | CloseScope(isolate_, prev_next_, prev_limit_); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 86 | // Allocate one handle in the parent scope. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 87 | DCHECK(current->level > current->sealed_level); |
| 88 | Handle<T> result(value, isolate_); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 89 | // Reinitialize the current scope (so that it's ready |
| 90 | // to be used or closed again). |
| 91 | prev_next_ = current->next; |
| 92 | prev_limit_ = current->limit; |
| 93 | current->level++; |
| 94 | return result; |
| 95 | } |
| 96 | |
| 97 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 98 | Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 99 | DCHECK(AllowHandleAllocation::IsAllowed()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 100 | HandleScopeData* data = isolate->handle_scope_data(); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 101 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 102 | Object** result = data->next; |
| 103 | if (result == data->limit) result = Extend(isolate); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 104 | // Update the current next field, set the value in the created |
| 105 | // handle, and return the result. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 106 | DCHECK(result < data->limit); |
| 107 | data->next = result + 1; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 108 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 109 | *result = value; |
| 110 | return result; |
| 111 | } |
| 112 | |
| 113 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 114 | Object** HandleScope::GetHandle(Isolate* isolate, Object* value) { |
| 115 | DCHECK(AllowHandleAllocation::IsAllowed()); |
| 116 | HandleScopeData* data = isolate->handle_scope_data(); |
| 117 | CanonicalHandleScope* canonical = data->canonical_scope; |
| 118 | return canonical ? canonical->Lookup(value) : CreateHandle(isolate, value); |
| 119 | } |
| 120 | |
| 121 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 122 | #ifdef DEBUG |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 123 | inline SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) { |
| 124 | // Make sure the current thread is allowed to create handles to begin with. |
| 125 | CHECK(AllowHandleAllocation::IsAllowed()); |
| 126 | HandleScopeData* current = isolate_->handle_scope_data(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 127 | // Shrink the current handle scope to make it impossible to do |
| 128 | // handle allocations without an explicit handle scope. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 129 | prev_limit_ = current->limit; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 130 | current->limit = current->next; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 131 | prev_sealed_level_ = current->sealed_level; |
| 132 | current->sealed_level = current->level; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 136 | inline SealHandleScope::~SealHandleScope() { |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 137 | // Restore state in current handle scope to re-enable handle |
| 138 | // allocations. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 139 | HandleScopeData* current = isolate_->handle_scope_data(); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 140 | DCHECK_EQ(current->next, current->limit); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 141 | current->limit = prev_limit_; |
| 142 | DCHECK_EQ(current->level, current->sealed_level); |
| 143 | current->sealed_level = prev_sealed_level_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 144 | } |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 145 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 146 | #endif |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 147 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 148 | } // namespace internal |
| 149 | } // namespace v8 |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 150 | |
| 151 | #endif // V8_HANDLES_INL_H_ |