Chromium Code Reviews| 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 UpdateExternalNewSpaceBit(); | |
| 219 // TODO(koda): On repeated/large external allocations for existing objects, | 221 // TODO(koda): On repeated/large external allocations for existing objects, |
| 220 // without any intervening normal allocation, GC will not trigger. | 222 // without any intervening normal allocation, GC will not trigger. |
| 221 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); | 223 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal()); |
| 222 } | 224 } |
| 223 | 225 |
| 224 // Called when the referent becomes unreachable. | 226 // Called when the referent becomes unreachable. |
| 225 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { | 227 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { |
| 226 EnsureFreeExternal(isolate); | 228 EnsureFreeExternal(isolate); |
| 227 Finalize(isolate, this, is_prologue_weak); | 229 Finalize(isolate, this, is_prologue_weak); |
| 228 } | 230 } |
| 229 | 231 |
| 230 // Called when the referent has moved, potentially between generations. | 232 // Called when the referent has moved, potentially between generations. |
| 231 void UpdateRelocated(Heap::Space before, Isolate* isolate) { | 233 void UpdateRelocated(Isolate* isolate) { |
| 232 isolate->heap()->FreeExternal(external_size_, before); | 234 Heap::Space after = SpaceForExternal(); |
| 233 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); | 235 Heap::Space before = WasPromotedSinceLastCall() ? Heap::kNew : after; |
|
siva
2014/03/11 16:35:01
Since we only promote new to old why can't this ch
koda
2014/03/11 17:35:45
Done.
My reasoning was to localize the assumption
| |
| 236 isolate->heap()->FreeExternal(external_size(), before); | |
| 237 isolate->heap()->AllocateExternal(external_size(), after); | |
|
siva
2014/03/11 16:35:01
if before == after it not necessary to do this Fre
koda
2014/03/11 17:35:45
Done.
| |
| 234 } | 238 } |
| 235 | 239 |
| 236 // Idempotent. Called when the handle is explicitly deleted or the | 240 // Idempotent. Called when the handle is explicitly deleted or the |
| 237 // referent becomes unreachable. | 241 // referent becomes unreachable. |
| 238 void EnsureFreeExternal(Isolate* isolate) { | 242 void EnsureFreeExternal(Isolate* isolate) { |
| 239 isolate->heap()->FreeExternal(external_size_, SpaceForExternal()); | 243 isolate->heap()->FreeExternal(external_size(), SpaceForExternal()); |
| 240 external_size_ = 0; | 244 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 } | 245 } |
| 249 | 246 |
| 250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { | 247 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { |
| 251 uword addr = reinterpret_cast<uword>(handle); | 248 uword addr = reinterpret_cast<uword>(handle); |
| 252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; | 249 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; |
| 253 } | 250 } |
| 254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); | 251 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); |
| 255 | 252 |
| 256 private: | 253 private: |
| 257 enum { | 254 enum { |
| 258 kWeakPersistentTag = 0, | 255 kWeakPersistentTag = 0, |
| 259 kPrologueWeakPersistentTag = 1, | 256 kPrologueWeakPersistentTag = 1, |
| 260 kWeakPersistentTagSize = 1, | 257 kWeakPersistentTagSize = 1, |
| 261 kWeakPersistentTagMask = 1, | 258 kWeakPersistentTagMask = 1, |
| 262 }; | 259 }; |
| 263 | 260 |
| 261 // This part of external_data_ is the number of externally allocated bytes. | |
| 262 // TODO(koda): Measure size in words instead. | |
| 263 class ExternalSizeBits : public BitField<intptr_t, 1, kBitsPerWord - 1> {}; | |
| 264 // This bit of external_data_ is true if the referent was created in new | |
| 265 // space and WasPromotedSinceLastCall has not yet detected any promotion. | |
| 266 class ExternalNewSpaceBit : public BitField<bool, 0, 1> {}; | |
| 267 // TODO(koda): Use bitfield also for the prologue tag. | |
| 268 | |
| 264 friend class FinalizablePersistentHandles; | 269 friend class FinalizablePersistentHandles; |
| 265 | 270 |
| 266 FinalizablePersistentHandle() | 271 FinalizablePersistentHandle() |
| 267 : raw_(NULL), | 272 : raw_(NULL), |
| 268 peer_(NULL), | 273 peer_(NULL), |
| 269 external_size_(0), | 274 external_data_(0), |
| 270 callback_(NULL) { } | 275 callback_(NULL) { } |
| 271 ~FinalizablePersistentHandle() { } | 276 ~FinalizablePersistentHandle() { } |
| 272 | 277 |
| 273 static void Finalize(Isolate* isolate, | 278 static void Finalize(Isolate* isolate, |
| 274 FinalizablePersistentHandle* handle, | 279 FinalizablePersistentHandle* handle, |
| 275 bool is_prologue_weak) { | 280 bool is_prologue_weak) { |
| 276 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); | 281 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); |
| 277 if (callback != NULL) { | 282 if (callback != NULL) { |
| 278 void* peer = handle->peer(); | 283 void* peer = handle->peer(); |
| 279 handle->Clear(); | 284 handle->Clear(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 296 ASSERT(!raw_->IsHeapObject()); | 301 ASSERT(!raw_->IsHeapObject()); |
| 297 } | 302 } |
| 298 void FreeHandle(FinalizablePersistentHandle* free_list) { | 303 void FreeHandle(FinalizablePersistentHandle* free_list) { |
| 299 Clear(); | 304 Clear(); |
| 300 SetNext(free_list); | 305 SetNext(free_list); |
| 301 } | 306 } |
| 302 | 307 |
| 303 void Clear() { | 308 void Clear() { |
| 304 raw_ = Object::null(); | 309 raw_ = Object::null(); |
| 305 peer_ = NULL; | 310 peer_ = NULL; |
| 306 external_size_ = 0; | 311 external_data_ = 0; |
| 307 callback_ = NULL; | 312 callback_ = NULL; |
| 308 } | 313 } |
| 309 | 314 |
| 315 intptr_t external_size() const { | |
| 316 return ExternalSizeBits::decode(external_data_); | |
| 317 } | |
| 318 | |
| 319 void set_external_size(intptr_t size) { | |
| 320 external_data_ = ExternalSizeBits::update(size, external_data_); | |
| 321 } | |
| 322 | |
| 323 void UpdateExternalNewSpaceBit() { | |
| 324 bool value = (SpaceForExternal() == Heap::kNew); | |
| 325 external_data_ = ExternalNewSpaceBit::update(value, external_data_); | |
| 326 } | |
|
siva
2014/03/11 16:35:01
The use of UpdateExternalNewSpaceBit to both set a
koda
2014/03/11 17:35:45
Done.
| |
| 327 | |
| 328 bool WasPromotedSinceLastCall() { | |
| 329 if (ExternalNewSpaceBit::decode(external_data_) && | |
| 330 SpaceForExternal() == Heap::kOld) { | |
| 331 UpdateExternalNewSpaceBit(); | |
| 332 return true; | |
| 333 } else { | |
| 334 return false; | |
| 335 } | |
| 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 |