| 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_RAW_OBJECT_H_ | 5 #ifndef VM_RAW_OBJECT_H_ |
| 6 #define VM_RAW_OBJECT_H_ | 6 #define VM_RAW_OBJECT_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/atomic.h" | 9 #include "vm/atomic.h" |
| 10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 const uword addr = reinterpret_cast<uword>(this); | 312 const uword addr = reinterpret_cast<uword>(this); |
| 313 return (addr & kNewObjectBits) != kNewObjectBits; | 313 return (addr & kNewObjectBits) != kNewObjectBits; |
| 314 } | 314 } |
| 315 | 315 |
| 316 // Support for GC marking bit. | 316 // Support for GC marking bit. |
| 317 bool IsMarked() const { | 317 bool IsMarked() const { |
| 318 return MarkBit::decode(ptr()->tags_); | 318 return MarkBit::decode(ptr()->tags_); |
| 319 } | 319 } |
| 320 void SetMarkBit() { | 320 void SetMarkBit() { |
| 321 ASSERT(!IsMarked()); | 321 ASSERT(!IsMarked()); |
| 322 UpdateTagBit<MarkBit>(true); |
| 323 } |
| 324 void SetMarkBitUnsynchronized() { |
| 325 ASSERT(!IsMarked()); |
| 322 uword tags = ptr()->tags_; | 326 uword tags = ptr()->tags_; |
| 323 ptr()->tags_ = MarkBit::update(true, tags); | 327 ptr()->tags_ = MarkBit::update(true, tags); |
| 324 } | 328 } |
| 325 void ClearMarkBit() { | 329 void ClearMarkBit() { |
| 326 ASSERT(IsMarked()); | 330 ASSERT(IsMarked()); |
| 327 uword tags = ptr()->tags_; | 331 UpdateTagBit<MarkBit>(false); |
| 328 ptr()->tags_ = MarkBit::update(false, tags); | |
| 329 } | 332 } |
| 330 | 333 |
| 331 // Support for GC watched bit. | 334 // Support for GC watched bit. |
| 335 // TODO(iposva): Get rid of this. |
| 332 bool IsWatched() const { | 336 bool IsWatched() const { |
| 333 return WatchedBit::decode(ptr()->tags_); | 337 return WatchedBit::decode(ptr()->tags_); |
| 334 } | 338 } |
| 335 void SetWatchedBit() { | 339 void SetWatchedBitUnsynchronized() { |
| 336 ASSERT(!IsWatched()); | 340 ASSERT(!IsWatched()); |
| 337 uword tags = ptr()->tags_; | 341 uword tags = ptr()->tags_; |
| 338 ptr()->tags_ = WatchedBit::update(true, tags); | 342 ptr()->tags_ = WatchedBit::update(true, tags); |
| 339 } | 343 } |
| 340 void ClearWatchedBit() { | 344 void ClearWatchedBitUnsynchronized() { |
| 341 ASSERT(IsWatched()); | |
| 342 uword tags = ptr()->tags_; | 345 uword tags = ptr()->tags_; |
| 343 ptr()->tags_ = WatchedBit::update(false, tags); | 346 ptr()->tags_ = WatchedBit::update(false, tags); |
| 344 } | 347 } |
| 345 | 348 |
| 346 // Support for object tags. | 349 // Support for object tags. |
| 347 bool IsCanonical() const { | 350 bool IsCanonical() const { |
| 348 return CanonicalObjectTag::decode(ptr()->tags_); | 351 return CanonicalObjectTag::decode(ptr()->tags_); |
| 349 } | 352 } |
| 350 void SetCanonical() { | 353 void SetCanonical() { |
| 351 uword tags = ptr()->tags_; | 354 UpdateTagBit<CanonicalObjectTag>(true); |
| 352 uword old_tags; | |
| 353 do { | |
| 354 old_tags = tags; | |
| 355 uword new_tags = CanonicalObjectTag::update(true, old_tags); | |
| 356 tags = AtomicOperations::CompareAndSwapWord( | |
| 357 &ptr()->tags_, old_tags, new_tags); | |
| 358 } while (tags != old_tags); | |
| 359 } | 355 } |
| 360 bool IsCreatedFromSnapshot() const { | 356 bool IsCreatedFromSnapshot() const { |
| 361 return CreatedFromSnapshotTag::decode(ptr()->tags_); | 357 return CreatedFromSnapshotTag::decode(ptr()->tags_); |
| 362 } | 358 } |
| 363 void SetCreatedFromSnapshot() { | 359 void SetCreatedFromSnapshot() { |
| 364 uword tags = ptr()->tags_; | 360 UpdateTagBit<CreatedFromSnapshotTag>(true); |
| 365 uword old_tags; | |
| 366 do { | |
| 367 old_tags = tags; | |
| 368 uword new_tags = CreatedFromSnapshotTag::update(true, old_tags); | |
| 369 tags = AtomicOperations::CompareAndSwapWord( | |
| 370 &ptr()->tags_, old_tags, new_tags); | |
| 371 } while (tags != old_tags); | |
| 372 } | 361 } |
| 373 | 362 |
| 374 // Support for GC remembered bit. | 363 // Support for GC remembered bit. |
| 375 bool IsRemembered() const { | 364 bool IsRemembered() const { |
| 376 return RememberedBit::decode(ptr()->tags_); | 365 return RememberedBit::decode(ptr()->tags_); |
| 377 } | 366 } |
| 378 void SetRememberedBit() { | 367 void SetRememberedBit() { |
| 379 ASSERT(!IsRemembered()); | 368 ASSERT(!IsRemembered()); |
| 369 UpdateTagBit<RememberedBit>(true); |
| 370 } |
| 371 void SetRememberedBitUnsynchronized() { |
| 372 ASSERT(!IsRemembered()); |
| 380 uword tags = ptr()->tags_; | 373 uword tags = ptr()->tags_; |
| 381 ptr()->tags_ = RememberedBit::update(true, tags); | 374 ptr()->tags_ = RememberedBit::update(true, tags); |
| 382 } | 375 } |
| 383 void ClearRememberedBit() { | 376 void ClearRememberedBit() { |
| 377 UpdateTagBit<RememberedBit>(false); |
| 378 } |
| 379 void ClearRememberedBitUnsynchronized() { |
| 384 uword tags = ptr()->tags_; | 380 uword tags = ptr()->tags_; |
| 385 ptr()->tags_ = RememberedBit::update(false, tags); | 381 ptr()->tags_ = RememberedBit::update(false, tags); |
| 386 } | 382 } |
| 387 | 383 |
| 388 bool IsDartInstance() { | 384 bool IsDartInstance() { |
| 389 return (!IsHeapObject() || (GetClassId() >= kInstanceCid)); | 385 return (!IsHeapObject() || (GetClassId() >= kInstanceCid)); |
| 390 } | 386 } |
| 391 bool IsFreeListElement() { | 387 bool IsFreeListElement() { |
| 392 return ((GetClassId() == kFreeListElement)); | 388 return ((GetClassId() == kFreeListElement)); |
| 393 } | 389 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 reinterpret_cast<uword>(this) - kHeapObjectTag); | 469 reinterpret_cast<uword>(this) - kHeapObjectTag); |
| 474 } | 470 } |
| 475 | 471 |
| 476 intptr_t SizeFromClass() const; | 472 intptr_t SizeFromClass() const; |
| 477 | 473 |
| 478 intptr_t GetClassId() const { | 474 intptr_t GetClassId() const { |
| 479 uword tags = ptr()->tags_; | 475 uword tags = ptr()->tags_; |
| 480 return ClassIdTag::decode(tags); | 476 return ClassIdTag::decode(tags); |
| 481 } | 477 } |
| 482 | 478 |
| 479 template<class TagBitField> |
| 480 void UpdateTagBit(bool value) { |
| 481 uword tags = ptr()->tags_; |
| 482 uword old_tags; |
| 483 do { |
| 484 old_tags = tags; |
| 485 uword new_tags = TagBitField::update(value, old_tags); |
| 486 tags = AtomicOperations::CompareAndSwapWord( |
| 487 &ptr()->tags_, old_tags, new_tags); |
| 488 } while (tags != old_tags); |
| 489 } |
| 490 |
| 483 // All writes to heap objects should ultimately pass through one of the | 491 // All writes to heap objects should ultimately pass through one of the |
| 484 // methods below or their counterparts in Object, to ensure that the | 492 // methods below or their counterparts in Object, to ensure that the |
| 485 // write barrier is correctly applied. | 493 // write barrier is correctly applied. |
| 486 | 494 |
| 487 template<typename type> | 495 template<typename type> |
| 488 void StorePointer(type const* addr, type value) { | 496 void StorePointer(type const* addr, type value) { |
| 489 // Ensure that this object contains the addr. | 497 // Ensure that this object contains the addr. |
| 490 ASSERT(Contains(reinterpret_cast<uword>(addr))); | 498 ASSERT(Contains(reinterpret_cast<uword>(addr))); |
| 491 VerifiedMemory::Write(const_cast<type*>(addr), value); | 499 VerifiedMemory::Write(const_cast<type*>(addr), value); |
| 492 // Filter stores based on source and target. | 500 // Filter stores based on source and target. |
| (...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2127 COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid == | 2135 COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid == |
| 2128 kTypedDataInt8ArrayViewCid + 15); | 2136 kTypedDataInt8ArrayViewCid + 15); |
| 2129 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14); | 2137 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14); |
| 2130 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1); | 2138 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1); |
| 2131 return (kNullCid - kTypedDataInt8ArrayCid); | 2139 return (kNullCid - kTypedDataInt8ArrayCid); |
| 2132 } | 2140 } |
| 2133 | 2141 |
| 2134 } // namespace dart | 2142 } // namespace dart |
| 2135 | 2143 |
| 2136 #endif // VM_RAW_OBJECT_H_ | 2144 #endif // VM_RAW_OBJECT_H_ |
| OLD | NEW |