Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: runtime/vm/raw_object.h

Issue 2954453002: VM: Reland Inline instance object hash code into object header on 64bit. (Closed)
Patch Set: Incorporate last minute code review feedback Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/raw_object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 RUNTIME_VM_RAW_OBJECT_H_ 5 #ifndef RUNTIME_VM_RAW_OBJECT_H_
6 #define RUNTIME_VM_RAW_OBJECT_H_ 6 #define RUNTIME_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/exceptions.h" 10 #include "vm/exceptions.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 kMarkBit = 0, 264 kMarkBit = 0,
265 kCanonicalBit = 1, 265 kCanonicalBit = 1,
266 kVMHeapObjectBit = 2, 266 kVMHeapObjectBit = 2,
267 kRememberedBit = 3, 267 kRememberedBit = 3,
268 kReservedTagPos = 4, // kReservedBit{100K,1M,10M} 268 kReservedTagPos = 4, // kReservedBit{100K,1M,10M}
269 kReservedTagSize = 4, 269 kReservedTagSize = 4,
270 kSizeTagPos = kReservedTagPos + kReservedTagSize, // = 8 270 kSizeTagPos = kReservedTagPos + kReservedTagSize, // = 8
271 kSizeTagSize = 8, 271 kSizeTagSize = 8,
272 kClassIdTagPos = kSizeTagPos + kSizeTagSize, // = 16 272 kClassIdTagPos = kSizeTagPos + kSizeTagSize, // = 16
273 kClassIdTagSize = 16, 273 kClassIdTagSize = 16,
274 #if defined(HASH_IN_OBJECT_HEADER)
275 kHashTagPos = kClassIdTagPos + kClassIdTagSize, // = 32
276 kHashTagSize = 16,
277 #endif
274 }; 278 };
275 279
276 COMPILE_ASSERT(kClassIdTagSize == (sizeof(classid_t) * kBitsPerByte)); 280 COMPILE_ASSERT(kClassIdTagSize == (sizeof(classid_t) * kBitsPerByte));
277 281
278 // Encodes the object size in the tag in units of object alignment. 282 // Encodes the object size in the tag in units of object alignment.
279 class SizeTag { 283 class SizeTag {
280 public: 284 public:
281 static const intptr_t kMaxSizeTag = ((1 << RawObject::kSizeTagSize) - 1) 285 static const intptr_t kMaxSizeTag = ((1 << RawObject::kSizeTagSize) - 1)
282 << kObjectAlignmentLog2; 286 << kObjectAlignmentLog2;
283 287
284 static uword encode(intptr_t size) { 288 static uword encode(intptr_t size) {
285 return SizeBits::encode(SizeToTagValue(size)); 289 return SizeBits::encode(SizeToTagValue(size));
286 } 290 }
287 291
288 static intptr_t decode(uword tag) { 292 static intptr_t decode(uword tag) {
289 return TagValueToSize(SizeBits::decode(tag)); 293 return TagValueToSize(SizeBits::decode(tag));
290 } 294 }
291 295
292 static uword update(intptr_t size, uword tag) { 296 static uword update(intptr_t size, uword tag) {
293 return SizeBits::update(SizeToTagValue(size), tag); 297 return SizeBits::update(SizeToTagValue(size), tag);
294 } 298 }
295 299
296 private: 300 private:
297 // The actual unscaled bit field used within the tag field. 301 // The actual unscaled bit field used within the tag field.
298 class SizeBits 302 class SizeBits
299 : public BitField<uword, intptr_t, kSizeTagPos, kSizeTagSize> {}; 303 : public BitField<uint32_t, intptr_t, kSizeTagPos, kSizeTagSize> {};
300 304
301 static intptr_t SizeToTagValue(intptr_t size) { 305 static intptr_t SizeToTagValue(intptr_t size) {
302 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 306 ASSERT(Utils::IsAligned(size, kObjectAlignment));
303 return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2); 307 return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2);
304 } 308 }
305 static intptr_t TagValueToSize(intptr_t value) { 309 static intptr_t TagValueToSize(intptr_t value) {
306 return value << kObjectAlignmentLog2; 310 return value << kObjectAlignmentLog2;
307 } 311 }
308 }; 312 };
309 313
310 class ClassIdTag 314 class ClassIdTag
311 : public BitField<uword, intptr_t, kClassIdTagPos, kClassIdTagSize> {}; 315 : public BitField<uint32_t, intptr_t, kClassIdTagPos, kClassIdTagSize> {};
312 316
313 bool IsWellFormed() const { 317 bool IsWellFormed() const {
314 uword value = reinterpret_cast<uword>(this); 318 uword value = reinterpret_cast<uword>(this);
315 return (value & kSmiTagMask) == 0 || 319 return (value & kSmiTagMask) == 0 ||
316 Utils::IsAligned(value - kHeapObjectTag, kWordSize); 320 Utils::IsAligned(value - kHeapObjectTag, kWordSize);
317 } 321 }
318 bool IsHeapObject() const { 322 bool IsHeapObject() const {
319 ASSERT(IsWellFormed()); 323 ASSERT(IsWellFormed());
320 uword value = reinterpret_cast<uword>(this); 324 uword value = reinterpret_cast<uword>(this);
321 return (value & kSmiTagMask) == kHeapObjectTag; 325 return (value & kSmiTagMask) == kHeapObjectTag;
(...skipping 23 matching lines...) Expand all
345 } 349 }
346 350
347 // Support for GC marking bit. 351 // Support for GC marking bit.
348 bool IsMarked() const { return MarkBit::decode(ptr()->tags_); } 352 bool IsMarked() const { return MarkBit::decode(ptr()->tags_); }
349 void SetMarkBit() { 353 void SetMarkBit() {
350 ASSERT(!IsMarked()); 354 ASSERT(!IsMarked());
351 UpdateTagBit<MarkBit>(true); 355 UpdateTagBit<MarkBit>(true);
352 } 356 }
353 void SetMarkBitUnsynchronized() { 357 void SetMarkBitUnsynchronized() {
354 ASSERT(!IsMarked()); 358 ASSERT(!IsMarked());
355 uword tags = ptr()->tags_; 359 uint32_t tags = ptr()->tags_;
356 ptr()->tags_ = MarkBit::update(true, tags); 360 ptr()->tags_ = MarkBit::update(true, tags);
357 } 361 }
358 void ClearMarkBit() { 362 void ClearMarkBit() {
359 ASSERT(IsMarked()); 363 ASSERT(IsMarked());
360 UpdateTagBit<MarkBit>(false); 364 UpdateTagBit<MarkBit>(false);
361 } 365 }
362 // Returns false if the bit was already set. 366 // Returns false if the bit was already set.
363 // TODO(koda): Add "must use result" annotation here, after we add support. 367 // TODO(koda): Add "must use result" annotation here, after we add support.
364 bool TryAcquireMarkBit() { return TryAcquireTagBit<MarkBit>(); } 368 bool TryAcquireMarkBit() { return TryAcquireTagBit<MarkBit>(); }
365 369
366 // Support for object tags. 370 // Support for object tags.
367 bool IsCanonical() const { return CanonicalObjectTag::decode(ptr()->tags_); } 371 bool IsCanonical() const { return CanonicalObjectTag::decode(ptr()->tags_); }
368 void SetCanonical() { UpdateTagBit<CanonicalObjectTag>(true); } 372 void SetCanonical() { UpdateTagBit<CanonicalObjectTag>(true); }
369 void ClearCanonical() { UpdateTagBit<CanonicalObjectTag>(false); } 373 void ClearCanonical() { UpdateTagBit<CanonicalObjectTag>(false); }
370 bool IsVMHeapObject() const { return VMHeapObjectTag::decode(ptr()->tags_); } 374 bool IsVMHeapObject() const { return VMHeapObjectTag::decode(ptr()->tags_); }
371 void SetVMHeapObject() { UpdateTagBit<VMHeapObjectTag>(true); } 375 void SetVMHeapObject() { UpdateTagBit<VMHeapObjectTag>(true); }
372 376
373 // Support for GC remembered bit. 377 // Support for GC remembered bit.
374 bool IsRemembered() const { return RememberedBit::decode(ptr()->tags_); } 378 bool IsRemembered() const { return RememberedBit::decode(ptr()->tags_); }
375 void SetRememberedBit() { 379 void SetRememberedBit() {
376 ASSERT(!IsRemembered()); 380 ASSERT(!IsRemembered());
377 UpdateTagBit<RememberedBit>(true); 381 UpdateTagBit<RememberedBit>(true);
378 } 382 }
379 void SetRememberedBitUnsynchronized() { 383 void SetRememberedBitUnsynchronized() {
380 ASSERT(!IsRemembered()); 384 ASSERT(!IsRemembered());
381 uword tags = ptr()->tags_; 385 uint32_t tags = ptr()->tags_;
382 ptr()->tags_ = RememberedBit::update(true, tags); 386 ptr()->tags_ = RememberedBit::update(true, tags);
383 } 387 }
384 void ClearRememberedBit() { UpdateTagBit<RememberedBit>(false); } 388 void ClearRememberedBit() { UpdateTagBit<RememberedBit>(false); }
385 void ClearRememberedBitUnsynchronized() { 389 void ClearRememberedBitUnsynchronized() {
386 uword tags = ptr()->tags_; 390 uint32_t tags = ptr()->tags_;
387 ptr()->tags_ = RememberedBit::update(false, tags); 391 ptr()->tags_ = RememberedBit::update(false, tags);
388 } 392 }
389 // Returns false if the bit was already set. 393 // Returns false if the bit was already set.
390 // TODO(koda): Add "must use result" annotation here, after we add support. 394 // TODO(koda): Add "must use result" annotation here, after we add support.
391 bool TryAcquireRememberedBit() { return TryAcquireTagBit<RememberedBit>(); } 395 bool TryAcquireRememberedBit() { return TryAcquireTagBit<RememberedBit>(); }
392 396
393 #define DEFINE_IS_CID(clazz) \ 397 #define DEFINE_IS_CID(clazz) \
394 bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); } 398 bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
395 CLASS_LIST(DEFINE_IS_CID) 399 CLASS_LIST(DEFINE_IS_CID)
396 #undef DEFINE_IS_CID 400 #undef DEFINE_IS_CID
397 401
398 #define DEFINE_IS_CID(clazz) \ 402 #define DEFINE_IS_CID(clazz) \
399 bool IsTypedData##clazz() const { \ 403 bool IsTypedData##clazz() const { \
400 return ((GetClassId() == kTypedData##clazz##Cid)); \ 404 return ((GetClassId() == kTypedData##clazz##Cid)); \
401 } \ 405 } \
402 bool IsTypedDataView##clazz() const { \ 406 bool IsTypedDataView##clazz() const { \
403 return ((GetClassId() == kTypedData##clazz##ViewCid)); \ 407 return ((GetClassId() == kTypedData##clazz##ViewCid)); \
404 } \ 408 } \
405 bool IsExternalTypedData##clazz() const { \ 409 bool IsExternalTypedData##clazz() const { \
406 return ((GetClassId() == kExternalTypedData##clazz##Cid)); \ 410 return ((GetClassId() == kExternalTypedData##clazz##Cid)); \
407 } 411 }
408 CLASS_LIST_TYPED_DATA(DEFINE_IS_CID) 412 CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
409 #undef DEFINE_IS_CID 413 #undef DEFINE_IS_CID
410 414
411 bool IsStringInstance() const { return IsStringClassId(GetClassId()); } 415 bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
416 bool IsRawNull() const { return GetClassId() == kNullCid; }
412 bool IsDartInstance() const { 417 bool IsDartInstance() const {
413 return (!IsHeapObject() || (GetClassId() >= kInstanceCid)); 418 return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
414 } 419 }
415 bool IsFreeListElement() const { 420 bool IsFreeListElement() const {
416 return ((GetClassId() == kFreeListElement)); 421 return ((GetClassId() == kFreeListElement));
417 } 422 }
418 bool IsForwardingCorpse() const { 423 bool IsForwardingCorpse() const {
419 return ((GetClassId() == kForwardingCorpse)); 424 return ((GetClassId() == kForwardingCorpse));
420 } 425 }
421 bool IsPseudoObject() const { 426 bool IsPseudoObject() const {
422 return IsFreeListElement() || IsForwardingCorpse(); 427 return IsFreeListElement() || IsForwardingCorpse();
423 } 428 }
424 429
425 intptr_t Size() const { 430 intptr_t Size() const {
426 uword tags = ptr()->tags_; 431 uint32_t tags = ptr()->tags_;
427 intptr_t result = SizeTag::decode(tags); 432 intptr_t result = SizeTag::decode(tags);
428 if (result != 0) { 433 if (result != 0) {
429 #if defined(DEBUG) 434 #if defined(DEBUG)
430 // TODO(22501) Array::MakeFixedLength has a race with this code: we might 435 // TODO(22501) Array::MakeFixedLength has a race with this code: we might
431 // have loaded tags field and then MakeFixedLength could have updated it 436 // have loaded tags field and then MakeFixedLength could have updated it
432 // leading to inconsistency between SizeFromClass() and 437 // leading to inconsistency between SizeFromClass() and
433 // SizeTag::decode(tags). We are working around it by reloading tags_ and 438 // SizeTag::decode(tags). We are working around it by reloading tags_ and
434 // recomputing size from tags. 439 // recomputing size from tags.
435 const intptr_t size_from_class = SizeFromClass(); 440 const intptr_t size_from_class = SizeFromClass();
436 if ((result > size_from_class) && (GetClassId() == kArrayCid) && 441 if ((result > size_from_class) && (GetClassId() == kArrayCid) &&
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 static bool IsTypedDataClassId(intptr_t index); 531 static bool IsTypedDataClassId(intptr_t index);
527 static bool IsTypedDataViewClassId(intptr_t index); 532 static bool IsTypedDataViewClassId(intptr_t index);
528 static bool IsExternalTypedDataClassId(intptr_t index); 533 static bool IsExternalTypedDataClassId(intptr_t index);
529 static bool IsInternalVMdefinedClassId(intptr_t index); 534 static bool IsInternalVMdefinedClassId(intptr_t index);
530 static bool IsVariableSizeClassId(intptr_t index); 535 static bool IsVariableSizeClassId(intptr_t index);
531 static bool IsImplicitFieldClassId(intptr_t index); 536 static bool IsImplicitFieldClassId(intptr_t index);
532 537
533 static intptr_t NumberOfTypedDataClasses(); 538 static intptr_t NumberOfTypedDataClasses();
534 539
535 private: 540 private:
536 uword tags_; // Various object tags (bits). 541 uint32_t tags_; // Various object tags (bits).
542 #if defined(HASH_IN_OBJECT_HEADER)
543 // On 64 bit there is a hash field in the header for the identity hash.
544 uint32_t hash_;
545 #endif
537 546
538 class MarkBit : public BitField<uword, bool, kMarkBit, 1> {}; 547 class MarkBit : public BitField<uint32_t, bool, kMarkBit, 1> {};
539 548
540 class RememberedBit : public BitField<uword, bool, kRememberedBit, 1> {}; 549 class RememberedBit : public BitField<uint32_t, bool, kRememberedBit, 1> {};
541 550
542 class CanonicalObjectTag : public BitField<uword, bool, kCanonicalBit, 1> {}; 551 class CanonicalObjectTag : public BitField<uint32_t, bool, kCanonicalBit, 1> {
552 };
543 553
544 class VMHeapObjectTag : public BitField<uword, bool, kVMHeapObjectBit, 1> {}; 554 class VMHeapObjectTag : public BitField<uint32_t, bool, kVMHeapObjectBit, 1> {
555 };
545 556
546 class ReservedBits 557 class ReservedBits
547 : public BitField<uword, intptr_t, kReservedTagPos, kReservedTagSize> {}; 558 : public BitField<uint32_t, intptr_t, kReservedTagPos, kReservedTagSize> {
559 };
548 560
549 // TODO(koda): After handling tags_, return const*, like Object::raw_ptr(). 561 // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
550 RawObject* ptr() const { 562 RawObject* ptr() const {
551 ASSERT(IsHeapObject()); 563 ASSERT(IsHeapObject());
552 return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) - 564 return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) -
553 kHeapObjectTag); 565 kHeapObjectTag);
554 } 566 }
555 567
556 intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor, 568 intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
557 intptr_t class_id); 569 intptr_t class_id);
558 570
559 intptr_t SizeFromClass() const; 571 intptr_t SizeFromClass() const;
560 572
561 intptr_t GetClassId() const { 573 intptr_t GetClassId() const {
562 uword tags = ptr()->tags_; 574 uint32_t tags = ptr()->tags_;
563 return ClassIdTag::decode(tags); 575 return ClassIdTag::decode(tags);
564 } 576 }
565 577
566 void SetClassId(intptr_t new_cid) { 578 void SetClassId(intptr_t new_cid) {
567 uword tags = ptr()->tags_; 579 uint32_t tags = ptr()->tags_;
568 ptr()->tags_ = ClassIdTag::update(new_cid, tags); 580 ptr()->tags_ = ClassIdTag::update(new_cid, tags);
569 } 581 }
570 582
571 template <class TagBitField> 583 template <class TagBitField>
572 void UpdateTagBit(bool value) { 584 void UpdateTagBit(bool value) {
573 uword tags = ptr()->tags_; 585 uint32_t tags = ptr()->tags_;
574 uword old_tags; 586 uint32_t old_tags;
575 do { 587 do {
576 old_tags = tags; 588 old_tags = tags;
577 uword new_tags = TagBitField::update(value, old_tags); 589 uint32_t new_tags = TagBitField::update(value, old_tags);
578 tags = AtomicOperations::CompareAndSwapWord(&ptr()->tags_, old_tags, 590 tags = AtomicOperations::CompareAndSwapUint32(&ptr()->tags_, old_tags,
579 new_tags); 591 new_tags);
580 } while (tags != old_tags); 592 } while (tags != old_tags);
581 } 593 }
582 594
583 template <class TagBitField> 595 template <class TagBitField>
584 bool TryAcquireTagBit() { 596 bool TryAcquireTagBit() {
585 uword tags = ptr()->tags_; 597 uint32_t tags = ptr()->tags_;
586 uword old_tags; 598 uint32_t old_tags;
587 do { 599 do {
588 old_tags = tags; 600 old_tags = tags;
589 if (TagBitField::decode(tags)) return false; 601 if (TagBitField::decode(tags)) return false;
590 uword new_tags = TagBitField::update(true, old_tags); 602 uint32_t new_tags = TagBitField::update(true, old_tags);
591 tags = AtomicOperations::CompareAndSwapWord(&ptr()->tags_, old_tags, 603 tags = AtomicOperations::CompareAndSwapUint32(&ptr()->tags_, old_tags,
592 new_tags); 604 new_tags);
593 } while (tags != old_tags); 605 } while (tags != old_tags);
594 return true; 606 return true;
595 } 607 }
596 608
597 // All writes to heap objects should ultimately pass through one of the 609 // All writes to heap objects should ultimately pass through one of the
598 // methods below or their counterparts in Object, to ensure that the 610 // methods below or their counterparts in Object, to ensure that the
599 // write barrier is correctly applied. 611 // write barrier is correctly applied.
600 612
601 template <typename type> 613 template <typename type>
602 void StorePointer(type const* addr, type value) { 614 void StorePointer(type const* addr, type value) {
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 // Is kKindShiftSize enough bits? 1323 // Is kKindShiftSize enough bits?
1312 COMPILE_ASSERT(kLastKind <= 1 << ((1 << kKindShiftSize) - 1)); 1324 COMPILE_ASSERT(kLastKind <= 1 << ((1 << kKindShiftSize) - 1));
1313 1325
1314 static const intptr_t kTryIndexPos = kKindShiftSize; 1326 static const intptr_t kTryIndexPos = kKindShiftSize;
1315 static const intptr_t kTryIndexSize = kBitsPerWord - kKindShiftSize; 1327 static const intptr_t kTryIndexSize = kBitsPerWord - kKindShiftSize;
1316 }; 1328 };
1317 1329
1318 private: 1330 private:
1319 RAW_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors); 1331 RAW_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors);
1320 1332
1321 int32_t length_; // Number of descriptors. 1333 // Number of descriptors. This only needs to be an int32_t, but we make it a
1334 // uword so that the variable length data is 64 bit aligned on 64 bit
1335 // platforms.
1336 uword length_;
1322 1337
1323 // Variable length data follows here. 1338 // Variable length data follows here.
1324 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); } 1339 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); }
1325 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); } 1340 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
1326 1341
1327 friend class Object; 1342 friend class Object;
1328 }; 1343 };
1329 1344
1330 1345
1331 // CodeSourceMap encodes a mapping from code PC ranges to source token 1346 // CodeSourceMap encodes a mapping from code PC ranges to source token
1332 // positions and the stack of inlined functions. 1347 // positions and the stack of inlined functions.
1333 class RawCodeSourceMap : public RawObject { 1348 class RawCodeSourceMap : public RawObject {
1334 private: 1349 private:
1335 RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap); 1350 RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap);
1336 1351
1337 int32_t length_; // Length in bytes. 1352 // Length in bytes. This only needs to be an int32_t, but we make it a uword
1353 // so that the variable length data is 64 bit aligned on 64 bit platforms.
1354 uword length_;
1338 1355
1339 // Variable length data follows here. 1356 // Variable length data follows here.
1340 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); } 1357 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); }
1341 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); } 1358 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
1342 1359
1343 friend class Object; 1360 friend class Object;
1344 }; 1361 };
1345 1362
1346 1363
1347 // StackMap is an immutable representation of the layout of the stack at a 1364 // StackMap is an immutable representation of the layout of the stack at a
1348 // PC. The stack map representation consists of a bit map which marks each 1365 // PC. The stack map representation consists of a bit map which marks each
1349 // live object index starting from the base of the frame. 1366 // live object index starting from the base of the frame.
1350 // 1367 //
1351 // The bit map representation is optimized for dense and small bit maps, without 1368 // The bit map representation is optimized for dense and small bit maps, without
1352 // any upper bound. 1369 // any upper bound.
1353 class RawStackMap : public RawObject { 1370 class RawStackMap : public RawObject {
1354 RAW_HEAP_OBJECT_IMPLEMENTATION(StackMap); 1371 RAW_HEAP_OBJECT_IMPLEMENTATION(StackMap);
1355 1372
1356 // Regarding changing this to a bitfield: ARM64 requires register_bit_count_ 1373 // Regarding changing this to a bitfield: ARM64 requires register_bit_count_
1357 // to be as large as 96, meaning 7 bits, leaving 25 bits for the length, or 1374 // to be as large as 96, meaning 7 bits, leaving 25 bits for the length, or
1358 // as large as ~33 million entries. If that is sufficient, then these two 1375 // as large as ~33 million entries. If that is sufficient, then these two
1359 // fields can be merged into a BitField. 1376 // fields can be merged into a BitField.
1360 int32_t length_; // Length of payload, in bits. 1377 int32_t length_; // Length of payload, in bits.
1361 int32_t slow_path_bit_count_; // Slow path live values, included in length_. 1378 int32_t slow_path_bit_count_; // Slow path live values, included in length_.
1362 1379
1363 // Offset from code entry point corresponding to this stack map 1380 // Offset from code entry point corresponding to this stack map
1364 // representation. 1381 // representation. This only needs to be an int32_t, but we make it a uword
1365 uint32_t pc_offset_; 1382 // so that the variable length data is 64 bit aligned on 64 bit platforms.
1383 uword pc_offset_;
1366 1384
1367 // Variable length data follows here (bitmap of the stack layout). 1385 // Variable length data follows here (bitmap of the stack layout).
1368 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); } 1386 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
1369 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); } 1387 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
1370 }; 1388 };
1371 1389
1372 1390
1373 class RawLocalVarDescriptors : public RawObject { 1391 class RawLocalVarDescriptors : public RawObject {
1374 public: 1392 public:
1375 enum VarInfoKind { 1393 enum VarInfoKind {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 index_kind = KindBits::update(kind, index_kind); 1427 index_kind = KindBits::update(kind, index_kind);
1410 } 1428 }
1411 int32_t index() const { return IndexBits::decode(index_kind) - kIndexBias; } 1429 int32_t index() const { return IndexBits::decode(index_kind) - kIndexBias; }
1412 void set_index(int32_t index) { 1430 void set_index(int32_t index) {
1413 index_kind = IndexBits::update(index + kIndexBias, index_kind); 1431 index_kind = IndexBits::update(index + kIndexBias, index_kind);
1414 } 1432 }
1415 }; 1433 };
1416 1434
1417 private: 1435 private:
1418 RAW_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors); 1436 RAW_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors);
1419 int32_t num_entries_; // Number of descriptors. 1437 // Number of descriptors. This only needs to be an int32_t, but we make it a
1438 // uword so that the variable length data is 64 bit aligned on 64 bit
1439 // platforms.
1440 uword num_entries_;
1420 1441
1421 RawObject** from() { 1442 RawObject** from() {
1422 return reinterpret_cast<RawObject**>(&ptr()->names()[0]); 1443 return reinterpret_cast<RawObject**>(&ptr()->names()[0]);
1423 } 1444 }
1424 RawString** names() { 1445 RawString** names() {
1425 // Array of [num_entries_] variable names. 1446 // Array of [num_entries_] variable names.
1426 OPEN_ARRAY_START(RawString*, RawString*); 1447 OPEN_ARRAY_START(RawString*, RawString*);
1427 } 1448 }
1428 RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); } 1449 RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
1429 1450
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 1938
1918 1939
1919 class RawOneByteString : public RawString { 1940 class RawOneByteString : public RawString {
1920 RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString); 1941 RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString);
1921 1942
1922 // Variable length data follows here. 1943 // Variable length data follows here.
1923 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); } 1944 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
1924 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); } 1945 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
1925 1946
1926 friend class ApiMessageReader; 1947 friend class ApiMessageReader;
1948 friend class RODataSerializationCluster;
1927 friend class SnapshotReader; 1949 friend class SnapshotReader;
1928 friend class RODataSerializationCluster; 1950 friend class String;
1929 }; 1951 };
1930 1952
1931 1953
1932 class RawTwoByteString : public RawString { 1954 class RawTwoByteString : public RawString {
1933 RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString); 1955 RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString);
1934 1956
1935 // Variable length data follows here. 1957 // Variable length data follows here.
1936 uint16_t* data() { OPEN_ARRAY_START(uint16_t, uint16_t); } 1958 uint16_t* data() { OPEN_ARRAY_START(uint16_t, uint16_t); }
1937 const uint16_t* data() const { OPEN_ARRAY_START(uint16_t, uint16_t); } 1959 const uint16_t* data() const { OPEN_ARRAY_START(uint16_t, uint16_t); }
1938 1960
1961 friend class RODataSerializationCluster;
1939 friend class SnapshotReader; 1962 friend class SnapshotReader;
1940 friend class RODataSerializationCluster; 1963 friend class String;
1941 }; 1964 };
1942 1965
1943 1966
1944 template <typename T> 1967 template <typename T>
1945 class ExternalStringData { 1968 class ExternalStringData {
1946 public: 1969 public:
1947 ExternalStringData(const T* data, void* peer, Dart_PeerFinalizer callback) 1970 ExternalStringData(const T* data, void* peer, Dart_PeerFinalizer callback)
1948 : data_(data), peer_(peer), callback_(callback) {} 1971 : data_(data), peer_(peer), callback_(callback) {}
1949 ~ExternalStringData() { 1972 ~ExternalStringData() {
1950 if (callback_ != NULL) (*callback_)(peer_); 1973 if (callback_ != NULL) (*callback_)(peer_);
(...skipping 15 matching lines...) Expand all
1966 1989
1967 class RawExternalOneByteString : public RawString { 1990 class RawExternalOneByteString : public RawString {
1968 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString); 1991 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString);
1969 1992
1970 public: 1993 public:
1971 typedef ExternalStringData<uint8_t> ExternalData; 1994 typedef ExternalStringData<uint8_t> ExternalData;
1972 1995
1973 private: 1996 private:
1974 ExternalData* external_data_; 1997 ExternalData* external_data_;
1975 friend class Api; 1998 friend class Api;
1999 friend class String;
1976 }; 2000 };
1977 2001
1978 2002
1979 class RawExternalTwoByteString : public RawString { 2003 class RawExternalTwoByteString : public RawString {
1980 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString); 2004 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString);
1981 2005
1982 public: 2006 public:
1983 typedef ExternalStringData<uint16_t> ExternalData; 2007 typedef ExternalStringData<uint16_t> ExternalData;
1984 2008
1985 private: 2009 private:
1986 ExternalData* external_data_; 2010 ExternalData* external_data_;
1987 friend class Api; 2011 friend class Api;
2012 friend class String;
1988 }; 2013 };
1989 2014
1990 2015
1991 class RawBool : public RawInstance { 2016 class RawBool : public RawInstance {
1992 RAW_HEAP_OBJECT_IMPLEMENTATION(Bool); 2017 RAW_HEAP_OBJECT_IMPLEMENTATION(Bool);
1993 2018
1994 bool value_; 2019 bool value_;
1995 }; 2020 };
1996 2021
1997 2022
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 kTypedDataInt8ArrayViewCid + 15); 2521 kTypedDataInt8ArrayViewCid + 15);
2497 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14); 2522 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14);
2498 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1); 2523 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1);
2499 return (kNullCid - kTypedDataInt8ArrayCid); 2524 return (kNullCid - kTypedDataInt8ArrayCid);
2500 } 2525 }
2501 2526
2502 2527
2503 } // namespace dart 2528 } // namespace dart
2504 2529
2505 #endif // RUNTIME_VM_RAW_OBJECT_H_ 2530 #endif // RUNTIME_VM_RAW_OBJECT_H_
OLDNEW
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/raw_object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698