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

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

Issue 2912863006: Inline instance object hash code into object header on 64 bit. (Closed)
Patch Set: Add assembler tests and other feedback from Ryan 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::MakeArray has a race with this code: we might have 435 // TODO(22501) Array::MakeArray has a race with this code: we might have
431 // loaded tags field and then MakeArray could have updated it leading 436 // loaded tags field and then MakeArray could have updated it leading
432 // to inconsistency between SizeFromClass() and SizeTag::decode(tags). 437 // to inconsistency between SizeFromClass() and SizeTag::decode(tags).
433 // We are working around it by reloading tags_ and recomputing 438 // We are working around it by reloading tags_ and recomputing
434 // size from tags. 439 // 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 static bool IsTypedDataClassId(intptr_t index); 491 static bool IsTypedDataClassId(intptr_t index);
487 static bool IsTypedDataViewClassId(intptr_t index); 492 static bool IsTypedDataViewClassId(intptr_t index);
488 static bool IsExternalTypedDataClassId(intptr_t index); 493 static bool IsExternalTypedDataClassId(intptr_t index);
489 static bool IsInternalVMdefinedClassId(intptr_t index); 494 static bool IsInternalVMdefinedClassId(intptr_t index);
490 static bool IsVariableSizeClassId(intptr_t index); 495 static bool IsVariableSizeClassId(intptr_t index);
491 static bool IsImplicitFieldClassId(intptr_t index); 496 static bool IsImplicitFieldClassId(intptr_t index);
492 497
493 static intptr_t NumberOfTypedDataClasses(); 498 static intptr_t NumberOfTypedDataClasses();
494 499
495 private: 500 private:
496 uword tags_; // Various object tags (bits). 501 uint32_t tags_; // Various object tags (bits).
502 #if defined(HASH_IN_OBJECT_HEADER)
503 // On 64 bit there is a hash field in the header for the identity hash.
504 uint32_t hash_;
505 #endif
497 506
498 class MarkBit : public BitField<uword, bool, kMarkBit, 1> {}; 507 class MarkBit : public BitField<uint32_t, bool, kMarkBit, 1> {};
499 508
500 class RememberedBit : public BitField<uword, bool, kRememberedBit, 1> {}; 509 class RememberedBit : public BitField<uint32_t, bool, kRememberedBit, 1> {};
501 510
502 class CanonicalObjectTag : public BitField<uword, bool, kCanonicalBit, 1> {}; 511 class CanonicalObjectTag : public BitField<uint32_t, bool, kCanonicalBit, 1> {
512 };
503 513
504 class VMHeapObjectTag : public BitField<uword, bool, kVMHeapObjectBit, 1> {}; 514 class VMHeapObjectTag : public BitField<uint32_t, bool, kVMHeapObjectBit, 1> {
515 };
505 516
506 class ReservedBits 517 class ReservedBits
507 : public BitField<uword, intptr_t, kReservedTagPos, kReservedTagSize> {}; 518 : public BitField<uint32_t, intptr_t, kReservedTagPos, kReservedTagSize> {
519 };
508 520
509 // TODO(koda): After handling tags_, return const*, like Object::raw_ptr(). 521 // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
510 RawObject* ptr() const { 522 RawObject* ptr() const {
511 ASSERT(IsHeapObject()); 523 ASSERT(IsHeapObject());
512 return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) - 524 return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) -
513 kHeapObjectTag); 525 kHeapObjectTag);
514 } 526 }
515 527
516 intptr_t SizeFromClass() const; 528 intptr_t SizeFromClass() const;
517 529
518 intptr_t GetClassId() const { 530 intptr_t GetClassId() const {
519 uword tags = ptr()->tags_; 531 uint32_t tags = ptr()->tags_;
520 return ClassIdTag::decode(tags); 532 return ClassIdTag::decode(tags);
521 } 533 }
522 534
523 void SetClassId(intptr_t new_cid) { 535 void SetClassId(intptr_t new_cid) {
524 uword tags = ptr()->tags_; 536 uint32_t tags = ptr()->tags_;
525 ptr()->tags_ = ClassIdTag::update(new_cid, tags); 537 ptr()->tags_ = ClassIdTag::update(new_cid, tags);
526 } 538 }
527 539
528 template <class TagBitField> 540 template <class TagBitField>
529 void UpdateTagBit(bool value) { 541 void UpdateTagBit(bool value) {
530 uword tags = ptr()->tags_; 542 uint32_t tags = ptr()->tags_;
531 uword old_tags; 543 uint32_t old_tags;
532 do { 544 do {
533 old_tags = tags; 545 old_tags = tags;
534 uword new_tags = TagBitField::update(value, old_tags); 546 uint32_t new_tags = TagBitField::update(value, old_tags);
535 tags = AtomicOperations::CompareAndSwapWord(&ptr()->tags_, old_tags, 547 tags = AtomicOperations::CompareAndSwapUint32(&ptr()->tags_, old_tags,
536 new_tags); 548 new_tags);
537 } while (tags != old_tags); 549 } while (tags != old_tags);
538 } 550 }
539 551
540 template <class TagBitField> 552 template <class TagBitField>
541 bool TryAcquireTagBit() { 553 bool TryAcquireTagBit() {
542 uword tags = ptr()->tags_; 554 uint32_t tags = ptr()->tags_;
543 uword old_tags; 555 uint32_t old_tags;
544 do { 556 do {
545 old_tags = tags; 557 old_tags = tags;
546 if (TagBitField::decode(tags)) return false; 558 if (TagBitField::decode(tags)) return false;
547 uword new_tags = TagBitField::update(true, old_tags); 559 uint32_t new_tags = TagBitField::update(true, old_tags);
548 tags = AtomicOperations::CompareAndSwapWord(&ptr()->tags_, old_tags, 560 tags = AtomicOperations::CompareAndSwapUint32(&ptr()->tags_, old_tags,
549 new_tags); 561 new_tags);
550 } while (tags != old_tags); 562 } while (tags != old_tags);
551 return true; 563 return true;
552 } 564 }
553 565
554 // All writes to heap objects should ultimately pass through one of the 566 // All writes to heap objects should ultimately pass through one of the
555 // methods below or their counterparts in Object, to ensure that the 567 // methods below or their counterparts in Object, to ensure that the
556 // write barrier is correctly applied. 568 // write barrier is correctly applied.
557 569
558 template <typename type> 570 template <typename type>
559 void StorePointer(type const* addr, type value) { 571 void StorePointer(type const* addr, type value) {
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 // Is kKindShiftSize enough bits? 1278 // Is kKindShiftSize enough bits?
1267 COMPILE_ASSERT(kLastKind <= 1 << ((1 << kKindShiftSize) - 1)); 1279 COMPILE_ASSERT(kLastKind <= 1 << ((1 << kKindShiftSize) - 1));
1268 1280
1269 static const intptr_t kTryIndexPos = kKindShiftSize; 1281 static const intptr_t kTryIndexPos = kKindShiftSize;
1270 static const intptr_t kTryIndexSize = kBitsPerWord - kKindShiftSize; 1282 static const intptr_t kTryIndexSize = kBitsPerWord - kKindShiftSize;
1271 }; 1283 };
1272 1284
1273 private: 1285 private:
1274 RAW_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors); 1286 RAW_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors);
1275 1287
1276 int32_t length_; // Number of descriptors. 1288 // Number of descriptors. This only needs to be an int32_t, but we make it a
1289 // uword so that the variable length data is 64 bit aligned on 64 bit
1290 // platforms.
1291 uword length_;
1277 1292
1278 // Variable length data follows here. 1293 // Variable length data follows here.
1279 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); } 1294 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); }
1280 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); } 1295 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
1281 1296
1282 friend class Object; 1297 friend class Object;
1283 }; 1298 };
1284 1299
1285 1300
1286 // CodeSourceMap encodes a mapping from code PC ranges to source token 1301 // CodeSourceMap encodes a mapping from code PC ranges to source token
1287 // positions and the stack of inlined functions. 1302 // positions and the stack of inlined functions.
1288 class RawCodeSourceMap : public RawObject { 1303 class RawCodeSourceMap : public RawObject {
1289 private: 1304 private:
1290 RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap); 1305 RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap);
1291 1306
1292 int32_t length_; // Length in bytes. 1307 // Length in bytes. This only needs to be an int32_t, but we make it a uword
1308 // so that the variable length data is 64 bit aligned on 64 bit platforms.
1309 uword length_;
1293 1310
1294 // Variable length data follows here. 1311 // Variable length data follows here.
1295 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); } 1312 uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); }
1296 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); } 1313 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
1297 1314
1298 friend class Object; 1315 friend class Object;
1299 }; 1316 };
1300 1317
1301 1318
1302 // StackMap is an immutable representation of the layout of the stack at a 1319 // StackMap is an immutable representation of the layout of the stack at a
1303 // PC. The stack map representation consists of a bit map which marks each 1320 // PC. The stack map representation consists of a bit map which marks each
1304 // live object index starting from the base of the frame. 1321 // live object index starting from the base of the frame.
1305 // 1322 //
1306 // The bit map representation is optimized for dense and small bit maps, without 1323 // The bit map representation is optimized for dense and small bit maps, without
1307 // any upper bound. 1324 // any upper bound.
1308 class RawStackMap : public RawObject { 1325 class RawStackMap : public RawObject {
1309 RAW_HEAP_OBJECT_IMPLEMENTATION(StackMap); 1326 RAW_HEAP_OBJECT_IMPLEMENTATION(StackMap);
1310 1327
1311 // Regarding changing this to a bitfield: ARM64 requires register_bit_count_ 1328 // Regarding changing this to a bitfield: ARM64 requires register_bit_count_
1312 // to be as large as 96, meaning 7 bits, leaving 25 bits for the length, or 1329 // to be as large as 96, meaning 7 bits, leaving 25 bits for the length, or
1313 // as large as ~33 million entries. If that is sufficient, then these two 1330 // as large as ~33 million entries. If that is sufficient, then these two
1314 // fields can be merged into a BitField. 1331 // fields can be merged into a BitField.
1315 int32_t length_; // Length of payload, in bits. 1332 int32_t length_; // Length of payload, in bits.
1316 int32_t slow_path_bit_count_; // Slow path live values, included in length_. 1333 int32_t slow_path_bit_count_; // Slow path live values, included in length_.
1317 1334
1318 // Offset from code entry point corresponding to this stack map 1335 // Offset from code entry point corresponding to this stack map
1319 // representation. 1336 // representation. This only needs to be an int32_t, but we make it a uword
1320 uint32_t pc_offset_; 1337 // so that the variable length data is 64 bit aligned on 64 bit platforms.
1338 uword pc_offset_;
1321 1339
1322 // Variable length data follows here (bitmap of the stack layout). 1340 // Variable length data follows here (bitmap of the stack layout).
1323 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); } 1341 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
1324 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); } 1342 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
1325 }; 1343 };
1326 1344
1327 1345
1328 class RawLocalVarDescriptors : public RawObject { 1346 class RawLocalVarDescriptors : public RawObject {
1329 public: 1347 public:
1330 enum VarInfoKind { 1348 enum VarInfoKind {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 index_kind = KindBits::update(kind, index_kind); 1382 index_kind = KindBits::update(kind, index_kind);
1365 } 1383 }
1366 int32_t index() const { return IndexBits::decode(index_kind) - kIndexBias; } 1384 int32_t index() const { return IndexBits::decode(index_kind) - kIndexBias; }
1367 void set_index(int32_t index) { 1385 void set_index(int32_t index) {
1368 index_kind = IndexBits::update(index + kIndexBias, index_kind); 1386 index_kind = IndexBits::update(index + kIndexBias, index_kind);
1369 } 1387 }
1370 }; 1388 };
1371 1389
1372 private: 1390 private:
1373 RAW_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors); 1391 RAW_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors);
1374 int32_t num_entries_; // Number of descriptors. 1392 // Number of descriptors. This only needs to be an int32_t, but we make it a
1393 // uword so that the variable length data is 64 bit aligned on 64 bit
1394 // platforms.
1395 uword num_entries_;
1375 1396
1376 RawObject** from() { 1397 RawObject** from() {
1377 return reinterpret_cast<RawObject**>(&ptr()->names()[0]); 1398 return reinterpret_cast<RawObject**>(&ptr()->names()[0]);
1378 } 1399 }
1379 RawString** names() { 1400 RawString** names() {
1380 // Array of [num_entries_] variable names. 1401 // Array of [num_entries_] variable names.
1381 OPEN_ARRAY_START(RawString*, RawString*); 1402 OPEN_ARRAY_START(RawString*, RawString*);
1382 } 1403 }
1383 RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); } 1404 RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
1384 1405
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 1893
1873 1894
1874 class RawOneByteString : public RawString { 1895 class RawOneByteString : public RawString {
1875 RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString); 1896 RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString);
1876 1897
1877 // Variable length data follows here. 1898 // Variable length data follows here.
1878 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); } 1899 uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
1879 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); } 1900 const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
1880 1901
1881 friend class ApiMessageReader; 1902 friend class ApiMessageReader;
1903 friend class RODataSerializationCluster;
1882 friend class SnapshotReader; 1904 friend class SnapshotReader;
1883 friend class RODataSerializationCluster; 1905 friend class String;
1884 }; 1906 };
1885 1907
1886 1908
1887 class RawTwoByteString : public RawString { 1909 class RawTwoByteString : public RawString {
1888 RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString); 1910 RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString);
1889 1911
1890 // Variable length data follows here. 1912 // Variable length data follows here.
1891 uint16_t* data() { OPEN_ARRAY_START(uint16_t, uint16_t); } 1913 uint16_t* data() { OPEN_ARRAY_START(uint16_t, uint16_t); }
1892 const uint16_t* data() const { OPEN_ARRAY_START(uint16_t, uint16_t); } 1914 const uint16_t* data() const { OPEN_ARRAY_START(uint16_t, uint16_t); }
1893 1915
1916 friend class RODataSerializationCluster;
1894 friend class SnapshotReader; 1917 friend class SnapshotReader;
1895 friend class RODataSerializationCluster; 1918 friend class String;
1896 }; 1919 };
1897 1920
1898 1921
1899 template <typename T> 1922 template <typename T>
1900 class ExternalStringData { 1923 class ExternalStringData {
1901 public: 1924 public:
1902 ExternalStringData(const T* data, void* peer, Dart_PeerFinalizer callback) 1925 ExternalStringData(const T* data, void* peer, Dart_PeerFinalizer callback)
1903 : data_(data), peer_(peer), callback_(callback) {} 1926 : data_(data), peer_(peer), callback_(callback) {}
1904 ~ExternalStringData() { 1927 ~ExternalStringData() {
1905 if (callback_ != NULL) (*callback_)(peer_); 1928 if (callback_ != NULL) (*callback_)(peer_);
(...skipping 15 matching lines...) Expand all
1921 1944
1922 class RawExternalOneByteString : public RawString { 1945 class RawExternalOneByteString : public RawString {
1923 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString); 1946 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString);
1924 1947
1925 public: 1948 public:
1926 typedef ExternalStringData<uint8_t> ExternalData; 1949 typedef ExternalStringData<uint8_t> ExternalData;
1927 1950
1928 private: 1951 private:
1929 ExternalData* external_data_; 1952 ExternalData* external_data_;
1930 friend class Api; 1953 friend class Api;
1954 friend class String;
1931 }; 1955 };
1932 1956
1933 1957
1934 class RawExternalTwoByteString : public RawString { 1958 class RawExternalTwoByteString : public RawString {
1935 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString); 1959 RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString);
1936 1960
1937 public: 1961 public:
1938 typedef ExternalStringData<uint16_t> ExternalData; 1962 typedef ExternalStringData<uint16_t> ExternalData;
1939 1963
1940 private: 1964 private:
1941 ExternalData* external_data_; 1965 ExternalData* external_data_;
1942 friend class Api; 1966 friend class Api;
1967 friend class String;
1943 }; 1968 };
1944 1969
1945 1970
1946 class RawBool : public RawInstance { 1971 class RawBool : public RawInstance {
1947 RAW_HEAP_OBJECT_IMPLEMENTATION(Bool); 1972 RAW_HEAP_OBJECT_IMPLEMENTATION(Bool);
1948 1973
1949 bool value_; 1974 bool value_;
1950 }; 1975 };
1951 1976
1952 1977
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 kTypedDataInt8ArrayViewCid + 15); 2476 kTypedDataInt8ArrayViewCid + 15);
2452 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14); 2477 COMPILE_ASSERT(kByteBufferCid == kExternalTypedDataInt8ArrayCid + 14);
2453 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1); 2478 COMPILE_ASSERT(kNullCid == kByteBufferCid + 1);
2454 return (kNullCid - kTypedDataInt8ArrayCid); 2479 return (kNullCid - kTypedDataInt8ArrayCid);
2455 } 2480 }
2456 2481
2457 2482
2458 } // namespace dart 2483 } // namespace dart
2459 2484
2460 #endif // RUNTIME_VM_RAW_OBJECT_H_ 2485 #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