| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_DART_API_STATE_H_ | 5 #ifndef VM_DART_API_STATE_H_ |
| 6 #define VM_DART_API_STATE_H_ | 6 #define VM_DART_API_STATE_H_ |
| 7 | 7 |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 | 9 |
| 10 #include "platform/thread.h" | 10 #include "platform/thread.h" |
| 11 #include "platform/utils.h" | 11 #include "platform/utils.h" |
| 12 #include "vm/bitfield.h" |
| 12 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
| 13 #include "vm/flags.h" | 14 #include "vm/flags.h" |
| 14 #include "vm/growable_array.h" | 15 #include "vm/growable_array.h" |
| 15 #include "vm/handles.h" | 16 #include "vm/handles.h" |
| 16 #include "vm/object.h" | 17 #include "vm/object.h" |
| 17 #include "vm/os.h" | 18 #include "vm/os.h" |
| 18 #include "vm/raw_object.h" | 19 #include "vm/raw_object.h" |
| 19 #include "vm/visitor.h" | 20 #include "vm/visitor.h" |
| 20 | 21 |
| 21 #include "vm/handles_impl.h" | 22 #include "vm/handles_impl.h" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 uword addr = reinterpret_cast<uword>(this); | 209 uword addr = reinterpret_cast<uword>(this); |
| 209 return reinterpret_cast<Dart_WeakPersistentHandle>( | 210 return reinterpret_cast<Dart_WeakPersistentHandle>( |
| 210 addr | kPrologueWeakPersistentTag); | 211 addr | kPrologueWeakPersistentTag); |
| 211 } | 212 } |
| 212 Dart_WeakPersistentHandle apiHandle() { | 213 Dart_WeakPersistentHandle apiHandle() { |
| 213 return reinterpret_cast<Dart_WeakPersistentHandle>(this); | 214 return reinterpret_cast<Dart_WeakPersistentHandle>(this); |
| 214 } | 215 } |
| 215 | 216 |
| 216 void SetExternalSize(intptr_t size, Isolate* isolate) { | 217 void SetExternalSize(intptr_t size, Isolate* isolate) { |
| 217 ASSERT(size >= 0); | 218 ASSERT(size >= 0); |
| 218 external_size_ = Utils::RoundUp(size, kObjectAlignment); | 219 set_external_size(Utils::RoundUp(size, kObjectAlignment)); |
| 220 if (SpaceForExternal() == Heap::kNew) { |
| 221 SetExternalNewSpaceBit(); |
| 222 } |
| 219 // TODO(koda): On repeated/large external allocations for existing objects, | 223 // TODO(koda): On repeated/large external allocations for existing objects, |
| 220 // without any intervening normal allocation, GC will not trigger. | 224 // without any intervening normal allocation, GC will not trigger. |
| 221 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); | 225 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal()); |
| 222 } | 226 } |
| 223 | 227 |
| 224 // Called when the referent becomes unreachable. | 228 // Called when the referent becomes unreachable. |
| 225 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { | 229 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { |
| 226 EnsureFreeExternal(isolate); | 230 EnsureFreeExternal(isolate); |
| 227 Finalize(isolate, this, is_prologue_weak); | 231 Finalize(isolate, this, is_prologue_weak); |
| 228 } | 232 } |
| 229 | 233 |
| 230 // Called when the referent has moved, potentially between generations. | 234 // Called when the referent has moved, potentially between generations. |
| 231 void UpdateRelocated(Heap::Space before, Isolate* isolate) { | 235 void UpdateRelocated(Isolate* isolate) { |
| 232 isolate->heap()->FreeExternal(external_size_, before); | 236 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) { |
| 233 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); | 237 isolate->heap()->FreeExternal(external_size(), Heap::kNew); |
| 238 isolate->heap()->AllocateExternal(external_size(), Heap::kOld); |
| 239 ClearExternalNewSpaceBit(); |
| 240 } |
| 234 } | 241 } |
| 235 | 242 |
| 236 // Idempotent. Called when the handle is explicitly deleted or the | 243 // Idempotent. Called when the handle is explicitly deleted or the |
| 237 // referent becomes unreachable. | 244 // referent becomes unreachable. |
| 238 void EnsureFreeExternal(Isolate* isolate) { | 245 void EnsureFreeExternal(Isolate* isolate) { |
| 239 isolate->heap()->FreeExternal(external_size_, SpaceForExternal()); | 246 isolate->heap()->FreeExternal(external_size(), SpaceForExternal()); |
| 240 external_size_ = 0; | 247 set_external_size(0); |
| 241 } | |
| 242 | |
| 243 // Returns the space to charge for the external size. | |
| 244 Heap::Space SpaceForExternal() const { | |
| 245 // Non-heap and VM-heap objects count as old space here. | |
| 246 return (raw_->IsHeapObject() && raw_->IsNewObject()) ? | |
| 247 Heap::kNew : Heap::kOld; | |
| 248 } | 248 } |
| 249 | 249 |
| 250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { | 250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { |
| 251 uword addr = reinterpret_cast<uword>(handle); | 251 uword addr = reinterpret_cast<uword>(handle); |
| 252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; | 252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; |
| 253 } | 253 } |
| 254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); | 254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); |
| 255 | 255 |
| 256 private: | 256 private: |
| 257 enum { | 257 enum { |
| 258 kWeakPersistentTag = 0, | 258 kWeakPersistentTag = 0, |
| 259 kPrologueWeakPersistentTag = 1, | 259 kPrologueWeakPersistentTag = 1, |
| 260 kWeakPersistentTagSize = 1, | 260 kWeakPersistentTagSize = 1, |
| 261 kWeakPersistentTagMask = 1, | 261 kWeakPersistentTagMask = 1, |
| 262 }; | 262 }; |
| 263 | 263 |
| 264 // This part of external_data_ is the number of externally allocated bytes. |
| 265 // TODO(koda): Measure size in words instead. |
| 266 class ExternalSizeBits : public BitField<intptr_t, 1, kBitsPerWord - 1> {}; |
| 267 // This bit of external_data_ is true if the referent was created in new |
| 268 // space and UpdateRelocated has not yet detected any promotion. |
| 269 class ExternalNewSpaceBit : public BitField<bool, 0, 1> {}; |
| 270 // TODO(koda): Use bitfield also for the prologue tag. |
| 271 |
| 264 friend class FinalizablePersistentHandles; | 272 friend class FinalizablePersistentHandles; |
| 265 | 273 |
| 266 FinalizablePersistentHandle() | 274 FinalizablePersistentHandle() |
| 267 : raw_(NULL), | 275 : raw_(NULL), |
| 268 peer_(NULL), | 276 peer_(NULL), |
| 269 external_size_(0), | 277 external_data_(0), |
| 270 callback_(NULL) { } | 278 callback_(NULL) { } |
| 271 ~FinalizablePersistentHandle() { } | 279 ~FinalizablePersistentHandle() { } |
| 272 | 280 |
| 273 static void Finalize(Isolate* isolate, | 281 static void Finalize(Isolate* isolate, |
| 274 FinalizablePersistentHandle* handle, | 282 FinalizablePersistentHandle* handle, |
| 275 bool is_prologue_weak) { | 283 bool is_prologue_weak) { |
| 276 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); | 284 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); |
| 277 if (callback != NULL) { | 285 if (callback != NULL) { |
| 278 void* peer = handle->peer(); | 286 void* peer = handle->peer(); |
| 279 handle->Clear(); | 287 handle->Clear(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 296 ASSERT(!raw_->IsHeapObject()); | 304 ASSERT(!raw_->IsHeapObject()); |
| 297 } | 305 } |
| 298 void FreeHandle(FinalizablePersistentHandle* free_list) { | 306 void FreeHandle(FinalizablePersistentHandle* free_list) { |
| 299 Clear(); | 307 Clear(); |
| 300 SetNext(free_list); | 308 SetNext(free_list); |
| 301 } | 309 } |
| 302 | 310 |
| 303 void Clear() { | 311 void Clear() { |
| 304 raw_ = Object::null(); | 312 raw_ = Object::null(); |
| 305 peer_ = NULL; | 313 peer_ = NULL; |
| 306 external_size_ = 0; | 314 external_data_ = 0; |
| 307 callback_ = NULL; | 315 callback_ = NULL; |
| 308 } | 316 } |
| 309 | 317 |
| 318 intptr_t external_size() const { |
| 319 return ExternalSizeBits::decode(external_data_); |
| 320 } |
| 321 |
| 322 void set_external_size(intptr_t size) { |
| 323 external_data_ = ExternalSizeBits::update(size, external_data_); |
| 324 } |
| 325 |
| 326 bool IsSetNewSpaceBit() const { |
| 327 return ExternalNewSpaceBit::decode(external_data_); |
| 328 } |
| 329 |
| 330 void SetExternalNewSpaceBit() { |
| 331 external_data_ = ExternalNewSpaceBit::update(true, external_data_); |
| 332 } |
| 333 |
| 334 void ClearExternalNewSpaceBit() { |
| 335 external_data_ = ExternalNewSpaceBit::update(false, external_data_); |
| 336 } |
| 337 |
| 338 // Returns the space to charge for the external size. |
| 339 Heap::Space SpaceForExternal() const { |
| 340 // Non-heap and VM-heap objects count as old space here. |
| 341 return (raw_->IsHeapObject() && raw_->IsNewObject()) ? |
| 342 Heap::kNew : Heap::kOld; |
| 343 } |
| 344 |
| 310 RawObject* raw_; | 345 RawObject* raw_; |
| 311 void* peer_; | 346 void* peer_; |
| 312 intptr_t external_size_; | 347 uword external_data_; |
| 313 Dart_WeakPersistentHandleFinalizer callback_; | 348 Dart_WeakPersistentHandleFinalizer callback_; |
| 314 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 349 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
| 315 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); | 350 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); |
| 316 }; | 351 }; |
| 317 | 352 |
| 318 | 353 |
| 319 // Local handles repository structure. | 354 // Local handles repository structure. |
| 320 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 355 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
| 321 static const int kLocalHandlesPerChunk = 64; | 356 static const int kLocalHandlesPerChunk = 64; |
| 322 static const int kOffsetOfRawPtrInLocalHandle = 0; | 357 static const int kOffsetOfRawPtrInLocalHandle = 0; |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 ApiNativeScope::Current()->zone()) {} | 893 ApiNativeScope::Current()->zone()) {} |
| 859 ApiGrowableArray() | 894 ApiGrowableArray() |
| 860 : BaseGrowableArray<T, ValueObject>( | 895 : BaseGrowableArray<T, ValueObject>( |
| 861 ApiNativeScope::Current()->zone()) {} | 896 ApiNativeScope::Current()->zone()) {} |
| 862 }; | 897 }; |
| 863 | 898 |
| 864 | 899 |
| 865 } // namespace dart | 900 } // namespace dart |
| 866 | 901 |
| 867 #endif // VM_DART_API_STATE_H_ | 902 #endif // VM_DART_API_STATE_H_ |
| OLD | NEW |