| 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_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
| 6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
| 7 | 7 |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 void operator^=(RawObject* value) { \ | 180 void operator^=(RawObject* value) { \ |
| 181 initializeHandle(this, value); \ | 181 initializeHandle(this, value); \ |
| 182 ASSERT(IsNull() || Is##object()); \ | 182 ASSERT(IsNull() || Is##object()); \ |
| 183 } \ | 183 } \ |
| 184 protected: /* NOLINT */ \ | 184 protected: /* NOLINT */ \ |
| 185 object() : super() {} \ | 185 object() : super() {} \ |
| 186 BASE_OBJECT_IMPLEMENTATION(object, super) \ | 186 BASE_OBJECT_IMPLEMENTATION(object, super) \ |
| 187 | 187 |
| 188 #define HEAP_OBJECT_IMPLEMENTATION(object, super) \ | 188 #define HEAP_OBJECT_IMPLEMENTATION(object, super) \ |
| 189 OBJECT_IMPLEMENTATION(object, super); \ | 189 OBJECT_IMPLEMENTATION(object, super); \ |
| 190 Raw##object* raw_ptr() const { \ | 190 const Raw##object* raw_ptr() const { \ |
| 191 ASSERT(raw() != null()); \ | 191 ASSERT(raw() != null()); \ |
| 192 return raw()->ptr(); \ | 192 return raw()->ptr(); \ |
| 193 } \ | 193 } \ |
| 194 SNAPSHOT_READER_SUPPORT(object) \ | 194 SNAPSHOT_READER_SUPPORT(object) \ |
| 195 friend class Isolate; \ | 195 friend class Isolate; \ |
| 196 friend class StackFrame; \ | 196 friend class StackFrame; \ |
| 197 | 197 |
| 198 // This macro is used to denote types that do not have a sub-type. | 198 // This macro is used to denote types that do not have a sub-type. |
| 199 #define FINAL_HEAP_OBJECT_IMPLEMENTATION(object, super) \ | 199 #define FINAL_HEAP_OBJECT_IMPLEMENTATION(object, super) \ |
| 200 public: /* NOLINT */ \ | 200 public: /* NOLINT */ \ |
| 201 void operator=(Raw##object* value) { \ | 201 void operator=(Raw##object* value) { \ |
| 202 raw_ = value; \ | 202 raw_ = value; \ |
| 203 CHECK_HANDLE(); \ | 203 CHECK_HANDLE(); \ |
| 204 } \ | 204 } \ |
| 205 void operator^=(RawObject* value) { \ | 205 void operator^=(RawObject* value) { \ |
| 206 raw_ = value; \ | 206 raw_ = value; \ |
| 207 CHECK_HANDLE(); \ | 207 CHECK_HANDLE(); \ |
| 208 } \ | 208 } \ |
| 209 private: /* NOLINT */ \ | 209 private: /* NOLINT */ \ |
| 210 object() : super() {} \ | 210 object() : super() {} \ |
| 211 BASE_OBJECT_IMPLEMENTATION(object, super) \ | 211 BASE_OBJECT_IMPLEMENTATION(object, super) \ |
| 212 Raw##object* raw_ptr() const { \ | 212 const Raw##object* raw_ptr() const { \ |
| 213 ASSERT(raw() != null()); \ | 213 ASSERT(raw() != null()); \ |
| 214 return raw()->ptr(); \ | 214 return raw()->ptr(); \ |
| 215 } \ | 215 } \ |
| 216 static intptr_t NextFieldOffset() { \ | 216 static intptr_t NextFieldOffset() { \ |
| 217 return -kWordSize; \ | 217 return -kWordSize; \ |
| 218 } \ | 218 } \ |
| 219 SNAPSHOT_READER_SUPPORT(object) \ | 219 SNAPSHOT_READER_SUPPORT(object) \ |
| 220 friend class Isolate; \ | 220 friend class Isolate; \ |
| 221 friend class StackFrame; \ | 221 friend class StackFrame; \ |
| 222 | 222 |
| 223 class Object { | 223 class Object { |
| 224 public: | 224 public: |
| 225 virtual ~Object() { } | 225 virtual ~Object() { } |
| 226 | 226 |
| 227 RawObject* raw() const { return raw_; } | 227 RawObject* raw() const { return raw_; } |
| 228 void operator=(RawObject* value) { | 228 void operator=(RawObject* value) { |
| 229 initializeHandle(this, value); | 229 initializeHandle(this, value); |
| 230 } | 230 } |
| 231 | 231 |
| 232 uword CompareAndSwapTags(uword old_tags, uword new_tags) const { |
| 233 return AtomicOperations::CompareAndSwapWord( |
| 234 &raw()->ptr()->tags_, old_tags, new_tags); |
| 235 } |
| 232 void set_tags(intptr_t value) const { | 236 void set_tags(intptr_t value) const { |
| 233 ASSERT(!IsNull()); | 237 ASSERT(!IsNull()); |
| 234 // TODO(asiva): Remove the capability of setting tags in general. The mask | 238 // TODO(asiva): Remove the capability of setting tags in general. The mask |
| 235 // here only allows for canonical and from_snapshot flags to be set. | 239 // here only allows for canonical and from_snapshot flags to be set. |
| 236 value = value & 0x0000000c; | 240 value = value & 0x0000000c; |
| 237 uword tags = raw()->ptr()->tags_; | 241 uword tags = raw()->ptr()->tags_; |
| 238 uword old_tags; | 242 uword old_tags; |
| 239 do { | 243 do { |
| 240 old_tags = tags; | 244 old_tags = tags; |
| 241 uword new_tags = (old_tags & ~0x0000000c) | value; | 245 uword new_tags = (old_tags & ~0x0000000c) | value; |
| 242 tags = AtomicOperations::CompareAndSwapWord( | 246 tags = CompareAndSwapTags(old_tags, new_tags); |
| 243 &raw()->ptr()->tags_, old_tags, new_tags); | |
| 244 } while (tags != old_tags); | 247 } while (tags != old_tags); |
| 245 } | 248 } |
| 246 void SetCreatedFromSnapshot() const { | 249 void SetCreatedFromSnapshot() const { |
| 247 ASSERT(!IsNull()); | 250 ASSERT(!IsNull()); |
| 248 raw()->SetCreatedFromSnapshot(); | 251 raw()->SetCreatedFromSnapshot(); |
| 249 } | 252 } |
| 250 bool IsCanonical() const { | 253 bool IsCanonical() const { |
| 251 ASSERT(!IsNull()); | 254 ASSERT(!IsNull()); |
| 252 return raw()->IsCanonical(); | 255 return raw()->IsCanonical(); |
| 253 } | 256 } |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 static intptr_t RoundedAllocationSize(intptr_t size) { | 574 static intptr_t RoundedAllocationSize(intptr_t size) { |
| 572 return Utils::RoundUp(size, kObjectAlignment); | 575 return Utils::RoundUp(size, kObjectAlignment); |
| 573 } | 576 } |
| 574 | 577 |
| 575 bool Contains(uword addr) const { | 578 bool Contains(uword addr) const { |
| 576 intptr_t this_size = raw()->Size(); | 579 intptr_t this_size = raw()->Size(); |
| 577 uword this_addr = RawObject::ToAddr(raw()); | 580 uword this_addr = RawObject::ToAddr(raw()); |
| 578 return (addr >= this_addr) && (addr < (this_addr + this_size)); | 581 return (addr >= this_addr) && (addr < (this_addr + this_size)); |
| 579 } | 582 } |
| 580 | 583 |
| 581 template<typename type> void StorePointer(type* addr, type value) const { | 584 // Start of field mutator guards. |
| 585 // |
| 586 // All writes to heap objects should ultimately pass through one of the |
| 587 // methods below, to ensure that the write barrier is correctly applied. |
| 588 |
| 589 template<typename type> |
| 590 void StorePointer(type const* addr, type value) const { |
| 582 // Ensure that this object contains the addr. | 591 // Ensure that this object contains the addr. |
| 583 ASSERT(Contains(reinterpret_cast<uword>(addr))); | 592 ASSERT(Contains(reinterpret_cast<uword>(addr))); |
| 584 *addr = value; | 593 *const_cast<type*>(addr) = value; |
| 585 // Filter stores based on source and target. | 594 // Filter stores based on source and target. |
| 586 if (!value->IsHeapObject()) return; | 595 if (!value->IsHeapObject()) return; |
| 587 if (value->IsNewObject() && raw()->IsOldObject() && | 596 if (value->IsNewObject() && raw()->IsOldObject() && |
| 588 !raw()->IsRemembered()) { | 597 !raw()->IsRemembered()) { |
| 589 raw()->SetRememberedBit(); | 598 raw()->SetRememberedBit(); |
| 590 Isolate::Current()->store_buffer()->AddObject(raw()); | 599 Isolate::Current()->store_buffer()->AddObject(raw()); |
| 591 } | 600 } |
| 592 } | 601 } |
| 593 | 602 |
| 603 // Store a range of pointers [from, from + count) into [to, to + count). |
| 604 // TODO(koda): Use this to fix Object::Clone's broken store buffer logic. |
| 605 void StorePointers(RawObject* const* to, |
| 606 RawObject* const* from, |
| 607 intptr_t count) { |
| 608 ASSERT(Contains(reinterpret_cast<uword>(to))); |
| 609 if (raw()->IsNewObject()) { |
| 610 memmove(const_cast<RawObject**>(to), from, count * kWordSize); |
| 611 } else { |
| 612 for (intptr_t i = 0; i < count; ++i) { |
| 613 StorePointer(&to[i], from[i]); |
| 614 } |
| 615 } |
| 616 } |
| 617 |
| 594 // Use for storing into an explicitly Smi-typed field of an object | 618 // Use for storing into an explicitly Smi-typed field of an object |
| 595 // (i.e., both the previous and new value are Smis). | 619 // (i.e., both the previous and new value are Smis). |
| 596 void StoreSmi(RawSmi** addr, RawSmi* value) const { | 620 void StoreSmi(RawSmi* const* addr, RawSmi* value) const { |
| 597 // Can't use Contains, as array length is initialized through this method. | 621 // Can't use Contains, as array length is initialized through this method. |
| 598 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); | 622 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); |
| 599 *addr = value; | 623 *const_cast<RawSmi**>(addr) = value; |
| 624 } |
| 625 |
| 626 template<typename FieldType> |
| 627 void StoreSimd128(const FieldType* addr, simd128_value_t value) const { |
| 628 ASSERT(Contains(reinterpret_cast<uword>(addr))); |
| 629 value.writeTo(const_cast<FieldType*>(addr)); |
| 600 } | 630 } |
| 601 | 631 |
| 602 // Needs two template arguments to allow assigning enums to fixed-size ints. | 632 // Needs two template arguments to allow assigning enums to fixed-size ints. |
| 603 template<typename FieldType, typename ValueType> | 633 template<typename FieldType, typename ValueType> |
| 604 void StoreNonPointer(FieldType* addr, ValueType value) const { | 634 void StoreNonPointer(const FieldType* addr, ValueType value) const { |
| 605 // Can't use Contains, as it uses tags_, which is set through this method. | 635 // Can't use Contains, as it uses tags_, which is set through this method. |
| 606 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); | 636 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); |
| 607 *addr = value; | 637 *const_cast<FieldType*>(addr) = value; |
| 608 } | 638 } |
| 609 | 639 |
| 610 // Fail at link time if StoreNonPointer is called with an object pointer. | 640 // Provides non-const access to non-pointer fields within the object. Such |
| 641 // access does not need a write barrier, but it is *not* GC-safe (since the |
| 642 // object might move), hence must be fully contained within a NoGCScope. |
| 643 template<typename FieldType> |
| 644 FieldType* UnsafeMutableNonPointer(const FieldType* addr) const { |
| 645 // Allow pointers at the end of variable-length data, and disallow pointers |
| 646 // within the header word. |
| 647 ASSERT(Contains(reinterpret_cast<uword>(addr) - 1) && |
| 648 Contains(reinterpret_cast<uword>(addr) - kWordSize)); |
| 649 // At least check that there is a NoGCScope, and hope it's big enough. |
| 650 ASSERT(Isolate::Current()->no_gc_scope_depth() > 0); |
| 651 return const_cast<FieldType*>(addr); |
| 652 } |
| 653 |
| 654 // Fail at link time if StoreNonPointer or UnsafeMutableNonPointer is |
| 655 // instantiated with an object pointer type. |
| 611 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ | 656 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ |
| 612 template<typename ValueType> \ | 657 template<typename ValueType> \ |
| 613 void StoreNonPointer(Raw##type** addr, ValueType value) const { \ | 658 void StoreNonPointer(Raw##type* const* addr, ValueType value) const { \ |
| 614 UnimplementedMethod(); \ | 659 UnimplementedMethod(); \ |
| 660 } \ |
| 661 Raw##type** UnsafeMutableNonPointer(Raw##type* const* addr) const { \ |
| 662 UnimplementedMethod(); \ |
| 663 return NULL; \ |
| 615 } | 664 } |
| 665 |
| 616 CLASS_LIST(STORE_NON_POINTER_ILLEGAL_TYPE); | 666 CLASS_LIST(STORE_NON_POINTER_ILLEGAL_TYPE); |
| 617 void UnimplementedMethod() const; | 667 void UnimplementedMethod() const; |
| 618 #undef STORE_NON_POINTER_ILLEGAL_TYPE | 668 #undef STORE_NON_POINTER_ILLEGAL_TYPE |
| 619 | 669 |
| 620 // Allocate an object and copy the body of 'orig'. | 670 // Allocate an object and copy the body of 'orig'. |
| 621 static RawObject* Clone(const Object& orig, Heap::Space space); | 671 static RawObject* Clone(const Object& orig, Heap::Space space); |
| 622 | 672 |
| 673 // End of field mutator guards. |
| 674 |
| 623 RawObject* raw_; // The raw object reference. | 675 RawObject* raw_; // The raw object reference. |
| 624 | 676 |
| 625 protected: | 677 protected: |
| 626 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; | 678 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; |
| 627 | 679 |
| 628 private: | 680 private: |
| 629 static intptr_t NextFieldOffset() { | 681 static intptr_t NextFieldOffset() { |
| 630 // Indicates this class cannot be extended by dart code. | 682 // Indicates this class cannot be extended by dart code. |
| 631 return -kWordSize; | 683 return -kWordSize; |
| 632 } | 684 } |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 Error* bound_error) const; | 1620 Error* bound_error) const; |
| 1569 | 1621 |
| 1570 // Return the internal or public name of a subvector of this type argument | 1622 // Return the internal or public name of a subvector of this type argument |
| 1571 // vector, e.g. "<T, dynamic, List<T>, int>". | 1623 // vector, e.g. "<T, dynamic, List<T>, int>". |
| 1572 RawString* SubvectorName(intptr_t from_index, | 1624 RawString* SubvectorName(intptr_t from_index, |
| 1573 intptr_t len, | 1625 intptr_t len, |
| 1574 NameVisibility name_visibility) const; | 1626 NameVisibility name_visibility) const; |
| 1575 | 1627 |
| 1576 RawArray* instantiations() const; | 1628 RawArray* instantiations() const; |
| 1577 void set_instantiations(const Array& value) const; | 1629 void set_instantiations(const Array& value) const; |
| 1578 RawAbstractType** TypeAddr(intptr_t index) const; | 1630 RawAbstractType* const* TypeAddr(intptr_t index) const; |
| 1579 void SetLength(intptr_t value) const; | 1631 void SetLength(intptr_t value) const; |
| 1580 | 1632 |
| 1581 FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, Object); | 1633 FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, Object); |
| 1582 friend class AbstractType; | 1634 friend class AbstractType; |
| 1583 friend class Class; | 1635 friend class Class; |
| 1584 }; | 1636 }; |
| 1585 | 1637 |
| 1586 | 1638 |
| 1587 class PatchClass : public Object { | 1639 class PatchClass : public Object { |
| 1588 public: | 1640 public: |
| (...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3101 | 3153 |
| 3102 | 3154 |
| 3103 class PcDescriptors : public Object { | 3155 class PcDescriptors : public Object { |
| 3104 public: | 3156 public: |
| 3105 void AddDescriptor(intptr_t index, | 3157 void AddDescriptor(intptr_t index, |
| 3106 uword pc, | 3158 uword pc, |
| 3107 RawPcDescriptors::Kind kind, | 3159 RawPcDescriptors::Kind kind, |
| 3108 int64_t deopt_id, | 3160 int64_t deopt_id, |
| 3109 int64_t token_pos, // Or deopt reason. | 3161 int64_t token_pos, // Or deopt reason. |
| 3110 intptr_t try_index) const { // Or deopt index. | 3162 intptr_t try_index) const { // Or deopt index. |
| 3163 NoGCScope no_gc; |
| 3111 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); | 3164 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); |
| 3112 rec->set_pc(pc); | 3165 rec->set_pc(pc); |
| 3113 rec->set_kind(kind); | 3166 rec->set_kind(kind); |
| 3114 ASSERT(Utils::IsInt(32, deopt_id)); | 3167 ASSERT(Utils::IsInt(32, deopt_id)); |
| 3115 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); | 3168 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); |
| 3116 ASSERT(Utils::IsInt(32, token_pos)); | 3169 ASSERT(Utils::IsInt(32, token_pos)); |
| 3117 rec->set_token_pos(static_cast<int32_t>(token_pos), | 3170 rec->set_token_pos(static_cast<int32_t>(token_pos), |
| 3118 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); | 3171 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); |
| 3119 ASSERT(Utils::IsInt(16, try_index)); | 3172 ASSERT(Utils::IsInt(16, try_index)); |
| 3120 rec->set_try_index(try_index); | 3173 rec->set_try_index(try_index); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3166 bool MoveNext() { | 3219 bool MoveNext() { |
| 3167 if (HasNext()) { | 3220 if (HasNext()) { |
| 3168 current_ix_ = next_ix_++; | 3221 current_ix_ = next_ix_++; |
| 3169 MoveToMatching(); | 3222 MoveToMatching(); |
| 3170 return true; | 3223 return true; |
| 3171 } else { | 3224 } else { |
| 3172 return false; | 3225 return false; |
| 3173 } | 3226 } |
| 3174 } | 3227 } |
| 3175 | 3228 |
| 3176 uword Pc() const { return descriptors_.recAt(current_ix_)->pc(); } | 3229 uword Pc() const { |
| 3230 NoGCScope no_gc; |
| 3231 return descriptors_.recAt(current_ix_)->pc(); |
| 3232 } |
| 3177 intptr_t DeoptId() const { | 3233 intptr_t DeoptId() const { |
| 3234 NoGCScope no_gc; |
| 3178 return descriptors_.recAt(current_ix_)->deopt_id(); | 3235 return descriptors_.recAt(current_ix_)->deopt_id(); |
| 3179 } | 3236 } |
| 3180 intptr_t TokenPos() const { | 3237 intptr_t TokenPos() const { |
| 3238 NoGCScope no_gc; |
| 3181 return descriptors_.recAt(current_ix_)->token_pos(); | 3239 return descriptors_.recAt(current_ix_)->token_pos(); |
| 3182 } | 3240 } |
| 3183 intptr_t TryIndex() const { | 3241 intptr_t TryIndex() const { |
| 3242 NoGCScope no_gc; |
| 3184 return descriptors_.recAt(current_ix_)->try_index(); | 3243 return descriptors_.recAt(current_ix_)->try_index(); |
| 3185 } | 3244 } |
| 3186 RawPcDescriptors::Kind Kind() const { | 3245 RawPcDescriptors::Kind Kind() const { |
| 3246 NoGCScope no_gc; |
| 3187 return descriptors_.recAt(current_ix_)->kind(); | 3247 return descriptors_.recAt(current_ix_)->kind(); |
| 3188 } | 3248 } |
| 3189 | 3249 |
| 3190 private: | 3250 private: |
| 3191 friend class PcDescriptors; | 3251 friend class PcDescriptors; |
| 3192 | 3252 |
| 3193 bool HasNext() const { return next_ix_ < descriptors_.Length(); } | 3253 bool HasNext() const { return next_ix_ < descriptors_.Length(); } |
| 3194 | 3254 |
| 3195 // For nested iterations, starting at element after. | 3255 // For nested iterations, starting at element after. |
| 3196 explicit Iterator(const Iterator& iter) | 3256 explicit Iterator(const Iterator& iter) |
| 3197 : ValueObject(), | 3257 : ValueObject(), |
| 3198 descriptors_(iter.descriptors_), | 3258 descriptors_(iter.descriptors_), |
| 3199 kind_mask_(iter.kind_mask_), | 3259 kind_mask_(iter.kind_mask_), |
| 3200 next_ix_(iter.next_ix_), | 3260 next_ix_(iter.next_ix_), |
| 3201 current_ix_(iter.current_ix_) {} | 3261 current_ix_(iter.current_ix_) {} |
| 3202 | 3262 |
| 3203 // Moves to record that matches kind_mask_. | 3263 // Moves to record that matches kind_mask_. |
| 3204 void MoveToMatching() { | 3264 void MoveToMatching() { |
| 3265 NoGCScope no_gc; |
| 3205 while (next_ix_ < descriptors_.Length()) { | 3266 while (next_ix_ < descriptors_.Length()) { |
| 3206 const RawPcDescriptors::PcDescriptorRec& rec = | 3267 const RawPcDescriptors::PcDescriptorRec& rec = |
| 3207 *descriptors_.recAt(next_ix_); | 3268 *descriptors_.recAt(next_ix_); |
| 3208 if ((rec.kind() & kind_mask_) != 0) { | 3269 if ((rec.kind() & kind_mask_) != 0) { |
| 3209 return; // Current is valid. | 3270 return; // Current is valid. |
| 3210 } else { | 3271 } else { |
| 3211 ++next_ix_; | 3272 ++next_ix_; |
| 3212 } | 3273 } |
| 3213 } | 3274 } |
| 3214 } | 3275 } |
| 3215 | 3276 |
| 3216 const PcDescriptors& descriptors_; | 3277 const PcDescriptors& descriptors_; |
| 3217 const intptr_t kind_mask_; | 3278 const intptr_t kind_mask_; |
| 3218 intptr_t next_ix_; | 3279 intptr_t next_ix_; |
| 3219 intptr_t current_ix_; | 3280 intptr_t current_ix_; |
| 3220 }; | 3281 }; |
| 3221 | 3282 |
| 3222 private: | 3283 private: |
| 3223 static const char* KindAsStr(RawPcDescriptors::Kind kind); | 3284 static const char* KindAsStr(RawPcDescriptors::Kind kind); |
| 3224 | 3285 |
| 3225 intptr_t Length() const; | 3286 intptr_t Length() const; |
| 3226 void SetLength(intptr_t value) const; | 3287 void SetLength(intptr_t value) const; |
| 3227 | 3288 |
| 3228 void SetRecordSizeInBytes(intptr_t value) const; | 3289 void SetRecordSizeInBytes(intptr_t value) const; |
| 3229 intptr_t RecordSizeInBytes() const; | 3290 intptr_t RecordSizeInBytes() const; |
| 3230 | 3291 |
| 3231 RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const { | 3292 RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const { |
| 3232 ASSERT((0 <= ix) && (ix < Length())); | 3293 ASSERT((0 <= ix) && (ix < Length())); |
| 3233 uint8_t* d = raw_ptr()->data() + (ix * RecordSizeInBytes()); | 3294 uint8_t* d = UnsafeMutableNonPointer(raw_ptr()->data()) + |
| 3295 (ix * RecordSizeInBytes()); |
| 3234 return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d); | 3296 return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d); |
| 3235 } | 3297 } |
| 3236 | 3298 |
| 3237 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); | 3299 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); |
| 3238 friend class Class; | 3300 friend class Class; |
| 3239 friend class Object; | 3301 friend class Object; |
| 3240 }; | 3302 }; |
| 3241 | 3303 |
| 3242 | 3304 |
| 3243 class Stackmap : public Object { | 3305 class Stackmap : public Object { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3420 | 3482 |
| 3421 // Returns true iff decompression yields the same instructions as the | 3483 // Returns true iff decompression yields the same instructions as the |
| 3422 // original. | 3484 // original. |
| 3423 bool VerifyDecompression(const GrowableArray<DeoptInstr*>& original, | 3485 bool VerifyDecompression(const GrowableArray<DeoptInstr*>& original, |
| 3424 const Array& deopt_table) const; | 3486 const Array& deopt_table) const; |
| 3425 | 3487 |
| 3426 private: | 3488 private: |
| 3427 intptr_t* EntryAddr(intptr_t index, intptr_t entry_offset) const { | 3489 intptr_t* EntryAddr(intptr_t index, intptr_t entry_offset) const { |
| 3428 ASSERT((index >=0) && (index < Length())); | 3490 ASSERT((index >=0) && (index < Length())); |
| 3429 intptr_t data_index = (index * kNumberOfEntries) + entry_offset; | 3491 intptr_t data_index = (index * kNumberOfEntries) + entry_offset; |
| 3430 return &raw_ptr()->data()[data_index]; | 3492 return &UnsafeMutableNonPointer(raw_ptr()->data())[data_index]; |
| 3431 } | 3493 } |
| 3432 | 3494 |
| 3433 void SetLength(intptr_t value) const; | 3495 void SetLength(intptr_t value) const; |
| 3434 | 3496 |
| 3435 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object); | 3497 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object); |
| 3436 friend class Class; | 3498 friend class Class; |
| 3437 }; | 3499 }; |
| 3438 | 3500 |
| 3439 | 3501 |
| 3440 // Object holding information about an IC: test classes and their | 3502 // Object holding information about an IC: test classes and their |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3849 Assembler* assembler, | 3911 Assembler* assembler, |
| 3850 bool optimized = false); | 3912 bool optimized = false); |
| 3851 static RawCode* FinalizeCode(const char* name, | 3913 static RawCode* FinalizeCode(const char* name, |
| 3852 Assembler* assembler, | 3914 Assembler* assembler, |
| 3853 bool optimized = false); | 3915 bool optimized = false); |
| 3854 static RawCode* LookupCode(uword pc); | 3916 static RawCode* LookupCode(uword pc); |
| 3855 static RawCode* LookupCodeInVmIsolate(uword pc); | 3917 static RawCode* LookupCodeInVmIsolate(uword pc); |
| 3856 static RawCode* FindCode(uword pc, int64_t timestamp); | 3918 static RawCode* FindCode(uword pc, int64_t timestamp); |
| 3857 | 3919 |
| 3858 int32_t GetPointerOffsetAt(int index) const { | 3920 int32_t GetPointerOffsetAt(int index) const { |
| 3921 NoGCScope no_gc; |
| 3859 return *PointerOffsetAddrAt(index); | 3922 return *PointerOffsetAddrAt(index); |
| 3860 } | 3923 } |
| 3861 intptr_t GetTokenIndexOfPC(uword pc) const; | 3924 intptr_t GetTokenIndexOfPC(uword pc) const; |
| 3862 | 3925 |
| 3863 enum { | 3926 enum { |
| 3864 kInvalidPc = -1 | 3927 kInvalidPc = -1 |
| 3865 }; | 3928 }; |
| 3866 | 3929 |
| 3867 // Returns 0 if code is not patchable | 3930 // Returns 0 if code is not patchable |
| 3868 uword GetEntryPatchPc() const; | 3931 uword GetEntryPatchPc() const; |
| 3869 uword GetPatchCodePc() const; | 3932 uword GetPatchCodePc() const; |
| 3870 | 3933 |
| 3871 uword GetLazyDeoptPc() const; | 3934 uword GetLazyDeoptPc() const; |
| 3872 | 3935 |
| 3873 // Find pc, return 0 if not found. | 3936 // Find pc, return 0 if not found. |
| 3874 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; | 3937 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; |
| 3875 intptr_t GetDeoptIdForOsr(uword pc) const; | 3938 intptr_t GetDeoptIdForOsr(uword pc) const; |
| 3876 | 3939 |
| 3877 RawString* Name() const; | 3940 RawString* Name() const; |
| 3878 RawString* PrettyName() const; | 3941 RawString* PrettyName() const; |
| 3879 | 3942 |
| 3880 int64_t compile_timestamp() const { | 3943 int64_t compile_timestamp() const { |
| 3881 return raw_ptr()->compile_timestamp_; | 3944 return raw_ptr()->compile_timestamp_; |
| 3882 } | 3945 } |
| 3883 | 3946 |
| 3884 intptr_t entry_patch_pc_offset() const { | 3947 intptr_t entry_patch_pc_offset() const { |
| 3885 return raw_ptr()->entry_patch_pc_offset_; | 3948 return raw_ptr()->entry_patch_pc_offset_; |
| 3886 } | 3949 } |
| 3887 void set_entry_patch_pc_offset(intptr_t pc) const { | 3950 void set_entry_patch_pc_offset(intptr_t pc) const { |
| 3888 raw_ptr()->entry_patch_pc_offset_ = pc; | 3951 StoreNonPointer(&raw_ptr()->entry_patch_pc_offset_, pc); |
| 3889 } | 3952 } |
| 3890 | 3953 |
| 3891 | 3954 |
| 3892 intptr_t patch_code_pc_offset() const { | 3955 intptr_t patch_code_pc_offset() const { |
| 3893 return raw_ptr()->patch_code_pc_offset_; | 3956 return raw_ptr()->patch_code_pc_offset_; |
| 3894 } | 3957 } |
| 3895 void set_patch_code_pc_offset(intptr_t pc) const { | 3958 void set_patch_code_pc_offset(intptr_t pc) const { |
| 3896 raw_ptr()->patch_code_pc_offset_ = pc; | 3959 StoreNonPointer(&raw_ptr()->patch_code_pc_offset_, pc); |
| 3897 } | 3960 } |
| 3898 | 3961 |
| 3899 | 3962 |
| 3900 intptr_t lazy_deopt_pc_offset() const { | 3963 intptr_t lazy_deopt_pc_offset() const { |
| 3901 return raw_ptr()->lazy_deopt_pc_offset_; | 3964 return raw_ptr()->lazy_deopt_pc_offset_; |
| 3902 } | 3965 } |
| 3903 void set_lazy_deopt_pc_offset(intptr_t pc) const { | 3966 void set_lazy_deopt_pc_offset(intptr_t pc) const { |
| 3904 raw_ptr()->lazy_deopt_pc_offset_ = pc; | 3967 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); |
| 3905 } | 3968 } |
| 3906 | 3969 |
| 3907 private: | 3970 private: |
| 3908 void set_state_bits(intptr_t bits) const; | 3971 void set_state_bits(intptr_t bits) const; |
| 3909 | 3972 |
| 3910 friend class RawObject; // For RawObject::SizeFromClass(). | 3973 friend class RawObject; // For RawObject::SizeFromClass(). |
| 3911 friend class RawCode; | 3974 friend class RawCode; |
| 3912 enum { | 3975 enum { |
| 3913 kOptimizedBit = 0, | 3976 kOptimizedBit = 0, |
| 3914 kAliveBit = 1, | 3977 kAliveBit = 1, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3952 | 4015 |
| 3953 void set_pointer_offsets_length(intptr_t value) { | 4016 void set_pointer_offsets_length(intptr_t value) { |
| 3954 // The number of fixups is limited to 1-billion. | 4017 // The number of fixups is limited to 1-billion. |
| 3955 ASSERT(Utils::IsUint(30, value)); | 4018 ASSERT(Utils::IsUint(30, value)); |
| 3956 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4019 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
| 3957 } | 4020 } |
| 3958 int32_t* PointerOffsetAddrAt(int index) const { | 4021 int32_t* PointerOffsetAddrAt(int index) const { |
| 3959 ASSERT(index >= 0); | 4022 ASSERT(index >= 0); |
| 3960 ASSERT(index < pointer_offsets_length()); | 4023 ASSERT(index < pointer_offsets_length()); |
| 3961 // TODO(iposva): Unit test is missing for this functionality. | 4024 // TODO(iposva): Unit test is missing for this functionality. |
| 3962 return &raw_ptr()->data()[index]; | 4025 return &UnsafeMutableNonPointer(raw_ptr()->data())[index]; |
| 3963 } | 4026 } |
| 3964 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { | 4027 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { |
| 4028 NoGCScope no_gc; |
| 3965 *PointerOffsetAddrAt(index) = offset_in_instructions; | 4029 *PointerOffsetAddrAt(index) = offset_in_instructions; |
| 3966 } | 4030 } |
| 3967 | 4031 |
| 3968 intptr_t BinarySearchInSCallTable(uword pc) const; | 4032 intptr_t BinarySearchInSCallTable(uword pc) const; |
| 3969 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); | 4033 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); |
| 3970 | 4034 |
| 3971 // New is a private method as RawInstruction and RawCode objects should | 4035 // New is a private method as RawInstruction and RawCode objects should |
| 3972 // only be created using the Code::FinalizeCode method. This method creates | 4036 // only be created using the Code::FinalizeCode method. This method creates |
| 3973 // the RawInstruction and RawCode objects, sets up the pointer offsets | 4037 // the RawInstruction and RawCode objects, sets up the pointer offsets |
| 3974 // and links the two in a GC safe manner. | 4038 // and links the two in a GC safe manner. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4022 | 4086 |
| 4023 static intptr_t InstanceSize(intptr_t len) { | 4087 static intptr_t InstanceSize(intptr_t len) { |
| 4024 ASSERT(0 <= len && len <= kMaxElements); | 4088 ASSERT(0 <= len && len <= kMaxElements); |
| 4025 return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement)); | 4089 return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement)); |
| 4026 } | 4090 } |
| 4027 | 4091 |
| 4028 static RawContext* New(intptr_t num_variables, | 4092 static RawContext* New(intptr_t num_variables, |
| 4029 Heap::Space space = Heap::kNew); | 4093 Heap::Space space = Heap::kNew); |
| 4030 | 4094 |
| 4031 private: | 4095 private: |
| 4032 RawInstance** InstanceAddr(intptr_t context_index) const { | 4096 RawInstance* const* InstanceAddr(intptr_t context_index) const { |
| 4033 ASSERT((context_index >= 0) && (context_index < num_variables())); | 4097 ASSERT((context_index >= 0) && (context_index < num_variables())); |
| 4034 return &raw_ptr()->data()[context_index]; | 4098 return &raw_ptr()->data()[context_index]; |
| 4035 } | 4099 } |
| 4036 | 4100 |
| 4037 void set_isolate(Isolate* isolate) const { | 4101 void set_isolate(Isolate* isolate) const { |
| 4038 StoreNonPointer(&raw_ptr()->isolate_, isolate); | 4102 StoreNonPointer(&raw_ptr()->isolate_, isolate); |
| 4039 } | 4103 } |
| 4040 | 4104 |
| 4041 void set_num_variables(intptr_t num_variables) const { | 4105 void set_num_variables(intptr_t num_variables) const { |
| 4042 StoreNonPointer(&raw_ptr()->num_variables_, num_variables); | 4106 StoreNonPointer(&raw_ptr()->num_variables_, num_variables); |
| (...skipping 1711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5754 friend class ExternalOneByteString; | 5818 friend class ExternalOneByteString; |
| 5755 friend class ExternalTwoByteString; | 5819 friend class ExternalTwoByteString; |
| 5756 // So that the MarkingVisitor can print a debug string from a NoHandleScope. | 5820 // So that the MarkingVisitor can print a debug string from a NoHandleScope. |
| 5757 friend class MarkingVisitor; | 5821 friend class MarkingVisitor; |
| 5758 }; | 5822 }; |
| 5759 | 5823 |
| 5760 | 5824 |
| 5761 class OneByteString : public AllStatic { | 5825 class OneByteString : public AllStatic { |
| 5762 public: | 5826 public: |
| 5763 static uint16_t CharAt(const String& str, intptr_t index) { | 5827 static uint16_t CharAt(const String& str, intptr_t index) { |
| 5828 NoGCScope no_gc; |
| 5764 return *CharAddr(str, index); | 5829 return *CharAddr(str, index); |
| 5765 } | 5830 } |
| 5766 | 5831 |
| 5767 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { | 5832 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { |
| 5833 NoGCScope no_gc; |
| 5768 *CharAddr(str, index) = code_unit; | 5834 *CharAddr(str, index) = code_unit; |
| 5769 } | 5835 } |
| 5770 static RawOneByteString* EscapeSpecialCharacters(const String& str); | 5836 static RawOneByteString* EscapeSpecialCharacters(const String& str); |
| 5771 // We use the same maximum elements for all strings. | 5837 // We use the same maximum elements for all strings. |
| 5772 static const intptr_t kBytesPerElement = 1; | 5838 static const intptr_t kBytesPerElement = 1; |
| 5773 static const intptr_t kMaxElements = String::kMaxElements; | 5839 static const intptr_t kMaxElements = String::kMaxElements; |
| 5774 | 5840 |
| 5775 static intptr_t data_offset() { | 5841 static intptr_t data_offset() { |
| 5776 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); | 5842 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); |
| 5777 } | 5843 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5856 | 5922 |
| 5857 static RawOneByteString* null() { | 5923 static RawOneByteString* null() { |
| 5858 return reinterpret_cast<RawOneByteString*>(Object::null()); | 5924 return reinterpret_cast<RawOneByteString*>(Object::null()); |
| 5859 } | 5925 } |
| 5860 | 5926 |
| 5861 private: | 5927 private: |
| 5862 static RawOneByteString* raw(const String& str) { | 5928 static RawOneByteString* raw(const String& str) { |
| 5863 return reinterpret_cast<RawOneByteString*>(str.raw()); | 5929 return reinterpret_cast<RawOneByteString*>(str.raw()); |
| 5864 } | 5930 } |
| 5865 | 5931 |
| 5866 static RawOneByteString* raw_ptr(const String& str) { | 5932 static const RawOneByteString* raw_ptr(const String& str) { |
| 5867 return reinterpret_cast<RawOneByteString*>(str.raw_ptr()); | 5933 return reinterpret_cast<const RawOneByteString*>(str.raw_ptr()); |
| 5868 } | 5934 } |
| 5869 | 5935 |
| 5870 static uint8_t* CharAddr(const String& str, intptr_t index) { | 5936 static uint8_t* CharAddr(const String& str, intptr_t index) { |
| 5871 ASSERT((index >= 0) && (index < str.Length())); | 5937 ASSERT((index >= 0) && (index < str.Length())); |
| 5872 ASSERT(str.IsOneByteString()); | 5938 ASSERT(str.IsOneByteString()); |
| 5873 NoGCScope no_gc; | 5939 return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[index]; |
| 5874 return &raw_ptr(str)->data()[index]; | |
| 5875 } | 5940 } |
| 5876 | 5941 |
| 5877 static RawOneByteString* ReadFrom(SnapshotReader* reader, | 5942 static RawOneByteString* ReadFrom(SnapshotReader* reader, |
| 5878 intptr_t object_id, | 5943 intptr_t object_id, |
| 5879 intptr_t tags, | 5944 intptr_t tags, |
| 5880 Snapshot::Kind kind); | 5945 Snapshot::Kind kind); |
| 5881 | 5946 |
| 5882 friend class Class; | 5947 friend class Class; |
| 5883 friend class String; | 5948 friend class String; |
| 5884 friend class ExternalOneByteString; | 5949 friend class ExternalOneByteString; |
| 5885 friend class SnapshotReader; | 5950 friend class SnapshotReader; |
| 5886 friend class StringHasher; | 5951 friend class StringHasher; |
| 5887 }; | 5952 }; |
| 5888 | 5953 |
| 5889 | 5954 |
| 5890 class TwoByteString : public AllStatic { | 5955 class TwoByteString : public AllStatic { |
| 5891 public: | 5956 public: |
| 5892 static uint16_t CharAt(const String& str, intptr_t index) { | 5957 static uint16_t CharAt(const String& str, intptr_t index) { |
| 5958 NoGCScope no_gc; |
| 5893 return *CharAddr(str, index); | 5959 return *CharAddr(str, index); |
| 5894 } | 5960 } |
| 5895 | 5961 |
| 5896 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { | 5962 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { |
| 5963 NoGCScope no_gc; |
| 5897 *CharAddr(str, index) = ch; | 5964 *CharAddr(str, index) = ch; |
| 5898 } | 5965 } |
| 5899 | 5966 |
| 5900 static RawTwoByteString* EscapeSpecialCharacters(const String& str); | 5967 static RawTwoByteString* EscapeSpecialCharacters(const String& str); |
| 5901 | 5968 |
| 5902 // We use the same maximum elements for all strings. | 5969 // We use the same maximum elements for all strings. |
| 5903 static const intptr_t kBytesPerElement = 2; | 5970 static const intptr_t kBytesPerElement = 2; |
| 5904 static const intptr_t kMaxElements = String::kMaxElements; | 5971 static const intptr_t kMaxElements = String::kMaxElements; |
| 5905 | 5972 |
| 5906 static intptr_t data_offset() { | 5973 static intptr_t data_offset() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5958 } | 6025 } |
| 5959 | 6026 |
| 5960 | 6027 |
| 5961 static const ClassId kClassId = kTwoByteStringCid; | 6028 static const ClassId kClassId = kTwoByteStringCid; |
| 5962 | 6029 |
| 5963 private: | 6030 private: |
| 5964 static RawTwoByteString* raw(const String& str) { | 6031 static RawTwoByteString* raw(const String& str) { |
| 5965 return reinterpret_cast<RawTwoByteString*>(str.raw()); | 6032 return reinterpret_cast<RawTwoByteString*>(str.raw()); |
| 5966 } | 6033 } |
| 5967 | 6034 |
| 5968 static RawTwoByteString* raw_ptr(const String& str) { | 6035 static const RawTwoByteString* raw_ptr(const String& str) { |
| 5969 return reinterpret_cast<RawTwoByteString*>(str.raw_ptr()); | 6036 return reinterpret_cast<const RawTwoByteString*>(str.raw_ptr()); |
| 5970 } | 6037 } |
| 5971 | 6038 |
| 5972 static uint16_t* CharAddr(const String& str, intptr_t index) { | 6039 static uint16_t* CharAddr(const String& str, intptr_t index) { |
| 5973 ASSERT((index >= 0) && (index < str.Length())); | 6040 ASSERT((index >= 0) && (index < str.Length())); |
| 5974 ASSERT(str.IsTwoByteString()); | 6041 ASSERT(str.IsTwoByteString()); |
| 5975 NoGCScope no_gc; | 6042 return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[index]; |
| 5976 return &raw_ptr(str)->data()[index]; | |
| 5977 } | 6043 } |
| 5978 | 6044 |
| 5979 static RawTwoByteString* ReadFrom(SnapshotReader* reader, | 6045 static RawTwoByteString* ReadFrom(SnapshotReader* reader, |
| 5980 intptr_t object_id, | 6046 intptr_t object_id, |
| 5981 intptr_t tags, | 6047 intptr_t tags, |
| 5982 Snapshot::Kind kind); | 6048 Snapshot::Kind kind); |
| 5983 | 6049 |
| 5984 friend class Class; | 6050 friend class Class; |
| 5985 friend class String; | 6051 friend class String; |
| 5986 friend class SnapshotReader; | 6052 friend class SnapshotReader; |
| 5987 }; | 6053 }; |
| 5988 | 6054 |
| 5989 | 6055 |
| 5990 class ExternalOneByteString : public AllStatic { | 6056 class ExternalOneByteString : public AllStatic { |
| 5991 public: | 6057 public: |
| 5992 static uint16_t CharAt(const String& str, intptr_t index) { | 6058 static uint16_t CharAt(const String& str, intptr_t index) { |
| 6059 NoGCScope no_gc; |
| 5993 return *CharAddr(str, index); | 6060 return *CharAddr(str, index); |
| 5994 } | 6061 } |
| 5995 | 6062 |
| 5996 static void* GetPeer(const String& str) { | 6063 static void* GetPeer(const String& str) { |
| 5997 return raw_ptr(str)->external_data_->peer(); | 6064 return raw_ptr(str)->external_data_->peer(); |
| 5998 } | 6065 } |
| 5999 | 6066 |
| 6000 // We use the same maximum elements for all strings. | 6067 // We use the same maximum elements for all strings. |
| 6001 static const intptr_t kBytesPerElement = 1; | 6068 static const intptr_t kBytesPerElement = 1; |
| 6002 static const intptr_t kMaxElements = String::kMaxElements; | 6069 static const intptr_t kMaxElements = String::kMaxElements; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 6019 static RawOneByteString* EncodeIRI(const String& str); | 6086 static RawOneByteString* EncodeIRI(const String& str); |
| 6020 static RawOneByteString* DecodeIRI(const String& str); | 6087 static RawOneByteString* DecodeIRI(const String& str); |
| 6021 | 6088 |
| 6022 static const ClassId kClassId = kExternalOneByteStringCid; | 6089 static const ClassId kClassId = kExternalOneByteStringCid; |
| 6023 | 6090 |
| 6024 private: | 6091 private: |
| 6025 static RawExternalOneByteString* raw(const String& str) { | 6092 static RawExternalOneByteString* raw(const String& str) { |
| 6026 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); | 6093 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); |
| 6027 } | 6094 } |
| 6028 | 6095 |
| 6029 static RawExternalOneByteString* raw_ptr(const String& str) { | 6096 static const RawExternalOneByteString* raw_ptr(const String& str) { |
| 6030 return reinterpret_cast<RawExternalOneByteString*>(str.raw_ptr()); | 6097 return reinterpret_cast<const RawExternalOneByteString*>(str.raw_ptr()); |
| 6031 } | 6098 } |
| 6032 | 6099 |
| 6033 static const uint8_t* CharAddr(const String& str, intptr_t index) { | 6100 static const uint8_t* CharAddr(const String& str, intptr_t index) { |
| 6034 ASSERT((index >= 0) && (index < str.Length())); | 6101 ASSERT((index >= 0) && (index < str.Length())); |
| 6035 ASSERT(str.IsExternalOneByteString()); | 6102 ASSERT(str.IsExternalOneByteString()); |
| 6036 NoGCScope no_gc; | |
| 6037 return &(raw_ptr(str)->external_data_->data()[index]); | 6103 return &(raw_ptr(str)->external_data_->data()[index]); |
| 6038 } | 6104 } |
| 6039 | 6105 |
| 6040 static void SetExternalData(const String& str, | 6106 static void SetExternalData(const String& str, |
| 6041 ExternalStringData<uint8_t>* data) { | 6107 ExternalStringData<uint8_t>* data) { |
| 6042 ASSERT(str.IsExternalOneByteString()); | 6108 ASSERT(str.IsExternalOneByteString()); |
| 6043 NoGCScope no_gc; | |
| 6044 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); | 6109 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); |
| 6045 } | 6110 } |
| 6046 | 6111 |
| 6047 static void Finalize(void* isolate_callback_data, | 6112 static void Finalize(void* isolate_callback_data, |
| 6048 Dart_WeakPersistentHandle handle, | 6113 Dart_WeakPersistentHandle handle, |
| 6049 void* peer); | 6114 void* peer); |
| 6050 | 6115 |
| 6051 static RawExternalOneByteString* ReadFrom(SnapshotReader* reader, | 6116 static RawExternalOneByteString* ReadFrom(SnapshotReader* reader, |
| 6052 intptr_t object_id, | 6117 intptr_t object_id, |
| 6053 intptr_t tags, | 6118 intptr_t tags, |
| 6054 Snapshot::Kind kind); | 6119 Snapshot::Kind kind); |
| 6055 | 6120 |
| 6056 static intptr_t NextFieldOffset() { | 6121 static intptr_t NextFieldOffset() { |
| 6057 // Indicates this class cannot be extended by dart code. | 6122 // Indicates this class cannot be extended by dart code. |
| 6058 return -kWordSize; | 6123 return -kWordSize; |
| 6059 } | 6124 } |
| 6060 | 6125 |
| 6061 friend class Class; | 6126 friend class Class; |
| 6062 friend class String; | 6127 friend class String; |
| 6063 friend class SnapshotReader; | 6128 friend class SnapshotReader; |
| 6064 }; | 6129 }; |
| 6065 | 6130 |
| 6066 | 6131 |
| 6067 class ExternalTwoByteString : public AllStatic { | 6132 class ExternalTwoByteString : public AllStatic { |
| 6068 public: | 6133 public: |
| 6069 static uint16_t CharAt(const String& str, intptr_t index) { | 6134 static uint16_t CharAt(const String& str, intptr_t index) { |
| 6135 NoGCScope no_gc; |
| 6070 return *CharAddr(str, index); | 6136 return *CharAddr(str, index); |
| 6071 } | 6137 } |
| 6072 | 6138 |
| 6073 static void* GetPeer(const String& str) { | 6139 static void* GetPeer(const String& str) { |
| 6074 return raw_ptr(str)->external_data_->peer(); | 6140 return raw_ptr(str)->external_data_->peer(); |
| 6075 } | 6141 } |
| 6076 | 6142 |
| 6077 // We use the same maximum elements for all strings. | 6143 // We use the same maximum elements for all strings. |
| 6078 static const intptr_t kBytesPerElement = 2; | 6144 static const intptr_t kBytesPerElement = 2; |
| 6079 static const intptr_t kMaxElements = String::kMaxElements; | 6145 static const intptr_t kMaxElements = String::kMaxElements; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6092 return reinterpret_cast<RawExternalTwoByteString*>(Object::null()); | 6158 return reinterpret_cast<RawExternalTwoByteString*>(Object::null()); |
| 6093 } | 6159 } |
| 6094 | 6160 |
| 6095 static const ClassId kClassId = kExternalTwoByteStringCid; | 6161 static const ClassId kClassId = kExternalTwoByteStringCid; |
| 6096 | 6162 |
| 6097 private: | 6163 private: |
| 6098 static RawExternalTwoByteString* raw(const String& str) { | 6164 static RawExternalTwoByteString* raw(const String& str) { |
| 6099 return reinterpret_cast<RawExternalTwoByteString*>(str.raw()); | 6165 return reinterpret_cast<RawExternalTwoByteString*>(str.raw()); |
| 6100 } | 6166 } |
| 6101 | 6167 |
| 6102 static RawExternalTwoByteString* raw_ptr(const String& str) { | 6168 static const RawExternalTwoByteString* raw_ptr(const String& str) { |
| 6103 return reinterpret_cast<RawExternalTwoByteString*>(str.raw_ptr()); | 6169 return reinterpret_cast<const RawExternalTwoByteString*>(str.raw_ptr()); |
| 6104 } | 6170 } |
| 6105 | 6171 |
| 6106 static const uint16_t* CharAddr(const String& str, intptr_t index) { | 6172 static const uint16_t* CharAddr(const String& str, intptr_t index) { |
| 6107 ASSERT((index >= 0) && (index < str.Length())); | 6173 ASSERT((index >= 0) && (index < str.Length())); |
| 6108 ASSERT(str.IsExternalTwoByteString()); | 6174 ASSERT(str.IsExternalTwoByteString()); |
| 6109 NoGCScope no_gc; | |
| 6110 return &(raw_ptr(str)->external_data_->data()[index]); | 6175 return &(raw_ptr(str)->external_data_->data()[index]); |
| 6111 } | 6176 } |
| 6112 | 6177 |
| 6113 static void SetExternalData(const String& str, | 6178 static void SetExternalData(const String& str, |
| 6114 ExternalStringData<uint16_t>* data) { | 6179 ExternalStringData<uint16_t>* data) { |
| 6115 ASSERT(str.IsExternalTwoByteString()); | 6180 ASSERT(str.IsExternalTwoByteString()); |
| 6116 NoGCScope no_gc; | |
| 6117 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); | 6181 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); |
| 6118 } | 6182 } |
| 6119 | 6183 |
| 6120 static void Finalize(void* isolate_callback_data, | 6184 static void Finalize(void* isolate_callback_data, |
| 6121 Dart_WeakPersistentHandle handle, | 6185 Dart_WeakPersistentHandle handle, |
| 6122 void* peer); | 6186 void* peer); |
| 6123 | 6187 |
| 6124 static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader, | 6188 static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader, |
| 6125 intptr_t object_id, | 6189 intptr_t object_id, |
| 6126 intptr_t tags, | 6190 intptr_t tags, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6261 RawArray* Slice(intptr_t start, | 6325 RawArray* Slice(intptr_t start, |
| 6262 intptr_t count, | 6326 intptr_t count, |
| 6263 bool with_type_argument) const; | 6327 bool with_type_argument) const; |
| 6264 | 6328 |
| 6265 protected: | 6329 protected: |
| 6266 static RawArray* New(intptr_t class_id, | 6330 static RawArray* New(intptr_t class_id, |
| 6267 intptr_t len, | 6331 intptr_t len, |
| 6268 Heap::Space space = Heap::kNew); | 6332 Heap::Space space = Heap::kNew); |
| 6269 | 6333 |
| 6270 private: | 6334 private: |
| 6271 RawObject** ObjectAddr(intptr_t index) const { | 6335 RawObject* const* ObjectAddr(intptr_t index) const { |
| 6272 // TODO(iposva): Determine if we should throw an exception here. | 6336 // TODO(iposva): Determine if we should throw an exception here. |
| 6273 ASSERT((index >= 0) && (index < Length())); | 6337 ASSERT((index >= 0) && (index < Length())); |
| 6274 return &raw_ptr()->data()[index]; | 6338 return &raw_ptr()->data()[index]; |
| 6275 } | 6339 } |
| 6276 | 6340 |
| 6277 void SetLength(intptr_t value) const { | 6341 void SetLength(intptr_t value) const { |
| 6278 // This is only safe because we create a new Smi, which does not cause | 6342 // This is only safe because we create a new Smi, which does not cause |
| 6279 // heap allocation. | 6343 // heap allocation. |
| 6280 StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 6344 StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
| 6281 } | 6345 } |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6601 } | 6665 } |
| 6602 | 6666 |
| 6603 intptr_t LengthInBytes() const { | 6667 intptr_t LengthInBytes() const { |
| 6604 intptr_t cid = raw()->GetClassId(); | 6668 intptr_t cid = raw()->GetClassId(); |
| 6605 return (ElementSizeInBytes(cid) * Length()); | 6669 return (ElementSizeInBytes(cid) * Length()); |
| 6606 } | 6670 } |
| 6607 | 6671 |
| 6608 void* DataAddr(intptr_t byte_offset) const { | 6672 void* DataAddr(intptr_t byte_offset) const { |
| 6609 ASSERT((byte_offset == 0) || | 6673 ASSERT((byte_offset == 0) || |
| 6610 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); | 6674 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); |
| 6611 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset); | 6675 return reinterpret_cast<void*>( |
| 6676 UnsafeMutableNonPointer(raw_ptr()->data()) + byte_offset); |
| 6612 } | 6677 } |
| 6613 | 6678 |
| 6614 virtual bool CanonicalizeEquals(const Instance& other) const; | 6679 virtual bool CanonicalizeEquals(const Instance& other) const; |
| 6615 | 6680 |
| 6616 #define TYPED_GETTER_SETTER(name, type) \ | 6681 #define TYPED_GETTER_SETTER(name, type) \ |
| 6617 type Get##name(intptr_t byte_offset) const { \ | 6682 type Get##name(intptr_t byte_offset) const { \ |
| 6683 NoGCScope no_gc; \ |
| 6618 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ | 6684 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ |
| 6619 } \ | 6685 } \ |
| 6620 void Set##name(intptr_t byte_offset, type value) const { \ | 6686 void Set##name(intptr_t byte_offset, type value) const { \ |
| 6687 NoGCScope no_gc; \ |
| 6621 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ | 6688 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ |
| 6622 } | 6689 } |
| 6623 TYPED_GETTER_SETTER(Int8, int8_t) | 6690 TYPED_GETTER_SETTER(Int8, int8_t) |
| 6624 TYPED_GETTER_SETTER(Uint8, uint8_t) | 6691 TYPED_GETTER_SETTER(Uint8, uint8_t) |
| 6625 TYPED_GETTER_SETTER(Int16, int16_t) | 6692 TYPED_GETTER_SETTER(Int16, int16_t) |
| 6626 TYPED_GETTER_SETTER(Uint16, uint16_t) | 6693 TYPED_GETTER_SETTER(Uint16, uint16_t) |
| 6627 TYPED_GETTER_SETTER(Int32, int32_t) | 6694 TYPED_GETTER_SETTER(Int32, int32_t) |
| 6628 TYPED_GETTER_SETTER(Uint32, uint32_t) | 6695 TYPED_GETTER_SETTER(Uint32, uint32_t) |
| 6629 TYPED_GETTER_SETTER(Int64, int64_t) | 6696 TYPED_GETTER_SETTER(Int64, int64_t) |
| 6630 TYPED_GETTER_SETTER(Uint64, uint64_t) | 6697 TYPED_GETTER_SETTER(Uint64, uint64_t) |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6858 class TypedDataView : public AllStatic { | 6925 class TypedDataView : public AllStatic { |
| 6859 public: | 6926 public: |
| 6860 static intptr_t ElementSizeInBytes(const Instance& view_obj) { | 6927 static intptr_t ElementSizeInBytes(const Instance& view_obj) { |
| 6861 ASSERT(!view_obj.IsNull()); | 6928 ASSERT(!view_obj.IsNull()); |
| 6862 intptr_t cid = view_obj.raw()->GetClassId(); | 6929 intptr_t cid = view_obj.raw()->GetClassId(); |
| 6863 return ElementSizeInBytes(cid); | 6930 return ElementSizeInBytes(cid); |
| 6864 } | 6931 } |
| 6865 | 6932 |
| 6866 static RawInstance* Data(const Instance& view_obj) { | 6933 static RawInstance* Data(const Instance& view_obj) { |
| 6867 ASSERT(!view_obj.IsNull()); | 6934 ASSERT(!view_obj.IsNull()); |
| 6868 return *reinterpret_cast<RawInstance**>(view_obj.raw_ptr() + kDataOffset); | 6935 return *reinterpret_cast<RawInstance* const*>( |
| 6936 view_obj.raw_ptr() + kDataOffset); |
| 6869 } | 6937 } |
| 6870 | 6938 |
| 6871 static RawSmi* OffsetInBytes(const Instance& view_obj) { | 6939 static RawSmi* OffsetInBytes(const Instance& view_obj) { |
| 6872 ASSERT(!view_obj.IsNull()); | 6940 ASSERT(!view_obj.IsNull()); |
| 6873 return *reinterpret_cast<RawSmi**>( | 6941 return *reinterpret_cast<RawSmi* const*>( |
| 6874 view_obj.raw_ptr() + kOffsetInBytesOffset); | 6942 view_obj.raw_ptr() + kOffsetInBytesOffset); |
| 6875 } | 6943 } |
| 6876 | 6944 |
| 6877 static RawSmi* Length(const Instance& view_obj) { | 6945 static RawSmi* Length(const Instance& view_obj) { |
| 6878 ASSERT(!view_obj.IsNull()); | 6946 ASSERT(!view_obj.IsNull()); |
| 6879 return *reinterpret_cast<RawSmi**>(view_obj.raw_ptr() + kLengthOffset); | 6947 return *reinterpret_cast<RawSmi* const*>( |
| 6948 view_obj.raw_ptr() + kLengthOffset); |
| 6880 } | 6949 } |
| 6881 | 6950 |
| 6882 static bool IsExternalTypedDataView(const Instance& view_obj) { | 6951 static bool IsExternalTypedDataView(const Instance& view_obj) { |
| 6883 const Instance& data = Instance::Handle(Data(view_obj)); | 6952 const Instance& data = Instance::Handle(Data(view_obj)); |
| 6884 intptr_t cid = data.raw()->GetClassId(); | 6953 intptr_t cid = data.raw()->GetClassId(); |
| 6885 ASSERT(RawObject::IsTypedDataClassId(cid) || | 6954 ASSERT(RawObject::IsTypedDataClassId(cid) || |
| 6886 RawObject::IsExternalTypedDataClassId(cid)); | 6955 RawObject::IsExternalTypedDataClassId(cid)); |
| 6887 return RawObject::IsExternalTypedDataClassId(cid); | 6956 return RawObject::IsExternalTypedDataClassId(cid); |
| 6888 } | 6957 } |
| 6889 | 6958 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 6916 kOffsetInBytesOffset = 2, | 6985 kOffsetInBytesOffset = 2, |
| 6917 kLengthOffset = 3, | 6986 kLengthOffset = 3, |
| 6918 }; | 6987 }; |
| 6919 }; | 6988 }; |
| 6920 | 6989 |
| 6921 | 6990 |
| 6922 class ByteBuffer : public AllStatic { | 6991 class ByteBuffer : public AllStatic { |
| 6923 public: | 6992 public: |
| 6924 static RawInstance* Data(const Instance& view_obj) { | 6993 static RawInstance* Data(const Instance& view_obj) { |
| 6925 ASSERT(!view_obj.IsNull()); | 6994 ASSERT(!view_obj.IsNull()); |
| 6926 return *reinterpret_cast<RawInstance**>(view_obj.raw_ptr() + kDataOffset); | 6995 return *reinterpret_cast<RawInstance* const*>( |
| 6996 view_obj.raw_ptr() + kDataOffset); |
| 6927 } | 6997 } |
| 6928 | 6998 |
| 6929 static intptr_t NumberOfFields() { | 6999 static intptr_t NumberOfFields() { |
| 6930 return kDataOffset; | 7000 return kDataOffset; |
| 6931 } | 7001 } |
| 6932 | 7002 |
| 6933 static intptr_t data_offset() { | 7003 static intptr_t data_offset() { |
| 6934 return kWordSize * kDataOffset; | 7004 return kWordSize * kDataOffset; |
| 6935 } | 7005 } |
| 6936 | 7006 |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7471 | 7541 |
| 7472 | 7542 |
| 7473 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7543 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
| 7474 intptr_t index) { | 7544 intptr_t index) { |
| 7475 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7545 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
| 7476 } | 7546 } |
| 7477 | 7547 |
| 7478 } // namespace dart | 7548 } // namespace dart |
| 7479 | 7549 |
| 7480 #endif // VM_OBJECT_H_ | 7550 #endif // VM_OBJECT_H_ |
| OLD | NEW |