| 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 |