OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 | 71 |
72 template <typename T> | 72 template <typename T> |
73 inline T** Handle<T>::location() const { | 73 inline T** Handle<T>::location() const { |
74 ASSERT(location_ == NULL || !(*location_)->IsFailure()); | 74 ASSERT(location_ == NULL || !(*location_)->IsFailure()); |
75 SLOW_ASSERT(location_ == NULL || IsDereferenceAllowed(false)); | 75 SLOW_ASSERT(location_ == NULL || IsDereferenceAllowed(false)); |
76 return location_; | 76 return location_; |
77 } | 77 } |
78 | 78 |
79 #ifdef DEBUG | 79 #ifdef DEBUG |
80 template <typename T> | 80 template <typename T> |
81 bool Handle<T>::IsDereferenceAllowed(bool allow_deferred) const { | 81 bool Handle<T>::IsDereferenceAllowed(bool explicitly_allow_deferred) const { |
82 ASSERT(location_ != NULL); | 82 ASSERT(location_ != NULL); |
83 Object* object = *BitCast<T**>(location_); | 83 Object* object = *BitCast<T**>(location_); |
84 if (object->IsSmi()) return true; | 84 if (object->IsSmi()) return true; |
85 HeapObject* heap_object = HeapObject::cast(object); | 85 HeapObject* heap_object = HeapObject::cast(object); |
86 Isolate* isolate = heap_object->GetIsolate(); | 86 Isolate* isolate = heap_object->GetIsolate(); |
87 Object** handle = reinterpret_cast<Object**>(location_); | 87 Object** handle = reinterpret_cast<Object**>(location_); |
88 Object** roots_array_start = isolate->heap()->roots_array_start(); | 88 Object** roots_array_start = isolate->heap()->roots_array_start(); |
89 if (roots_array_start <= handle && | 89 if (roots_array_start <= handle && |
90 handle < roots_array_start + Heap::kStrongRootListLength) { | 90 handle < roots_array_start + Heap::kStrongRootListLength) { |
91 return true; | 91 return true; |
92 } | 92 } |
93 if (isolate->optimizing_compiler_thread()->IsOptimizerThread() && | 93 if (!AllowHandleDereference::IsAllowed()) return false; |
94 !Heap::RelocationLock::IsLockedByOptimizerThread(isolate->heap())) { | 94 if (!explicitly_allow_deferred && |
95 return false; | 95 !AllowDeferredHandleDereference::IsAllowed()) { |
| 96 // Accessing maps and internalized strings is safe. |
| 97 if (heap_object->IsMap()) return true; |
| 98 if (heap_object->IsInternalizedString()) return true; |
| 99 return !isolate->IsDeferredHandle(handle); |
96 } | 100 } |
97 switch (isolate->HandleDereferenceGuardState()) { | 101 return true; |
98 case HandleDereferenceGuard::ALLOW: | |
99 return true; | |
100 case HandleDereferenceGuard::DISALLOW: | |
101 return false; | |
102 case HandleDereferenceGuard::DISALLOW_DEFERRED: | |
103 // Accessing maps and internalized strings is safe. | |
104 if (heap_object->IsMap()) return true; | |
105 if (heap_object->IsInternalizedString()) return true; | |
106 return allow_deferred || !isolate->IsDeferredHandle(handle); | |
107 } | |
108 return false; | |
109 } | 102 } |
110 #endif | 103 #endif |
111 | 104 |
112 | 105 |
113 | 106 |
114 HandleScope::HandleScope(Isolate* isolate) { | 107 HandleScope::HandleScope(Isolate* isolate) { |
115 v8::ImplementationUtilities::HandleScopeData* current = | 108 v8::ImplementationUtilities::HandleScopeData* current = |
116 isolate->handle_scope_data(); | 109 isolate->handle_scope_data(); |
117 isolate_ = isolate; | 110 isolate_ = isolate; |
118 prev_next_ = current->next; | 111 prev_next_ = current->next; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 // to be used or closed again). | 153 // to be used or closed again). |
161 prev_next_ = current->next; | 154 prev_next_ = current->next; |
162 prev_limit_ = current->limit; | 155 prev_limit_ = current->limit; |
163 current->level++; | 156 current->level++; |
164 return result; | 157 return result; |
165 } | 158 } |
166 | 159 |
167 | 160 |
168 template <typename T> | 161 template <typename T> |
169 T** HandleScope::CreateHandle(Isolate* isolate, T* value) { | 162 T** HandleScope::CreateHandle(Isolate* isolate, T* value) { |
| 163 ASSERT(AllowHandleAllocation::IsAllowed()); |
170 v8::ImplementationUtilities::HandleScopeData* current = | 164 v8::ImplementationUtilities::HandleScopeData* current = |
171 isolate->handle_scope_data(); | 165 isolate->handle_scope_data(); |
172 | 166 |
173 internal::Object** cur = current->next; | 167 internal::Object** cur = current->next; |
174 if (cur == current->limit) cur = Extend(isolate); | 168 if (cur == current->limit) cur = Extend(isolate); |
175 // Update the current next field, set the value in the created | 169 // Update the current next field, set the value in the created |
176 // handle, and return the result. | 170 // handle, and return the result. |
177 ASSERT(cur < current->limit); | 171 ASSERT(cur < current->limit); |
178 current->next = cur + 1; | 172 current->next = cur + 1; |
179 | 173 |
180 T** result = reinterpret_cast<T**>(cur); | 174 T** result = reinterpret_cast<T**>(cur); |
181 *result = value; | 175 *result = value; |
182 return result; | 176 return result; |
183 } | 177 } |
184 | 178 |
185 | 179 |
186 #ifdef DEBUG | 180 #ifdef DEBUG |
187 inline NoHandleAllocation::NoHandleAllocation(Isolate* isolate) | 181 inline RequireNewHandleScope::RequireNewHandleScope(Isolate* isolate) |
188 : isolate_(isolate) { | 182 : isolate_(isolate) { |
189 active_ = !isolate->optimizing_compiler_thread()->IsOptimizerThread(); | 183 // Make sure the current thread is allowed to create handles to begin with. |
190 if (active_) { | 184 CHECK(AllowHandleAllocation::IsAllowed()); |
191 // Shrink the current handle scope to make it impossible to do | 185 v8::ImplementationUtilities::HandleScopeData* current = |
192 // handle allocations without an explicit handle scope. | 186 isolate_->handle_scope_data(); |
193 v8::ImplementationUtilities::HandleScopeData* current = | 187 // Shrink the current handle scope to make it impossible to do |
194 isolate_->handle_scope_data(); | 188 // handle allocations without an explicit handle scope. |
195 limit_ = current->limit; | 189 current->limit = current->next; |
196 current->limit = current->next; | 190 |
197 level_ = current->level; | 191 level_ = current->level; |
198 current->level = 0; | 192 current->level = 0; |
199 } | |
200 } | 193 } |
201 | 194 |
202 | 195 |
203 inline NoHandleAllocation::~NoHandleAllocation() { | 196 inline RequireNewHandleScope::~RequireNewHandleScope() { |
204 if (active_) { | 197 // Restore state in current handle scope to re-enable handle |
205 // Restore state in current handle scope to re-enable handle | 198 // allocations. |
206 // allocations. | 199 v8::ImplementationUtilities::HandleScopeData* data = |
207 v8::ImplementationUtilities::HandleScopeData* current = | 200 isolate_->handle_scope_data(); |
208 isolate_->handle_scope_data(); | 201 ASSERT_EQ(0, data->level); |
209 ASSERT_EQ(0, current->level); | 202 data->level = level_; |
210 current->level = level_; | |
211 ASSERT_EQ(current->next, current->limit); | |
212 current->limit = limit_; | |
213 } | |
214 } | |
215 | |
216 | |
217 HandleDereferenceGuard::HandleDereferenceGuard(Isolate* isolate, State state) | |
218 : isolate_(isolate) { | |
219 old_state_ = isolate_->HandleDereferenceGuardState(); | |
220 isolate_->SetHandleDereferenceGuardState(state); | |
221 } | |
222 | |
223 | |
224 HandleDereferenceGuard::~HandleDereferenceGuard() { | |
225 isolate_->SetHandleDereferenceGuardState(old_state_); | |
226 } | 203 } |
227 | 204 |
228 #endif | 205 #endif |
229 | 206 |
230 } } // namespace v8::internal | 207 } } // namespace v8::internal |
231 | 208 |
232 #endif // V8_HANDLES_INL_H_ | 209 #endif // V8_HANDLES_INL_H_ |
OLD | NEW |