Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 static intptr_t RoundedAllocationSize(intptr_t size) { | 576 static intptr_t RoundedAllocationSize(intptr_t size) { |
| 574 return Utils::RoundUp(size, kObjectAlignment); | 577 return Utils::RoundUp(size, kObjectAlignment); |
| 575 } | 578 } |
| 576 | 579 |
| 577 bool Contains(uword addr) const { | 580 bool Contains(uword addr) const { |
| 578 intptr_t this_size = raw()->Size(); | 581 intptr_t this_size = raw()->Size(); |
| 579 uword this_addr = RawObject::ToAddr(raw()); | 582 uword this_addr = RawObject::ToAddr(raw()); |
| 580 return (addr >= this_addr) && (addr < (this_addr + this_size)); | 583 return (addr >= this_addr) && (addr < (this_addr + this_size)); |
| 581 } | 584 } |
| 582 | 585 |
| 583 template<typename type> void StorePointer(type* addr, type value) const { | 586 // Start of field mutator guards. |
| 587 // | |
| 588 // All writes to heap objects should ultimately pass through one of the | |
| 589 // methods below, to ensure that the write barrier is correctly applied. | |
| 590 | |
| 591 template<typename type> | |
| 592 void StorePointer(const type* addr, type value) const { | |
|
Ivan Posva
2014/10/10 23:52:11
type const* addr
to match the untemplated version
koda
2014/10/11 00:26:33
Done.
| |
| 584 // Ensure that this object contains the addr. | 593 // Ensure that this object contains the addr. |
| 585 ASSERT(Contains(reinterpret_cast<uword>(addr))); | 594 ASSERT(Contains(reinterpret_cast<uword>(addr))); |
| 586 *addr = value; | 595 *const_cast<type*>(addr) = value; |
| 587 // Filter stores based on source and target. | 596 // Filter stores based on source and target. |
| 588 if (!value->IsHeapObject()) return; | 597 if (!value->IsHeapObject()) return; |
| 589 if (value->IsNewObject() && raw()->IsOldObject() && | 598 if (value->IsNewObject() && raw()->IsOldObject() && |
| 590 !raw()->IsRemembered()) { | 599 !raw()->IsRemembered()) { |
| 591 raw()->SetRememberedBit(); | 600 raw()->SetRememberedBit(); |
| 592 Isolate::Current()->store_buffer()->AddObject(raw()); | 601 Isolate::Current()->store_buffer()->AddObject(raw()); |
| 593 } | 602 } |
| 594 } | 603 } |
| 595 | 604 |
| 605 // Store a range of pointers [from, from + count) into [to, to + count). | |
| 606 // TODO(koda): Use this to fix Object::Clone's broken store buffer logic. | |
| 607 void StorePointers(RawObject* const* to, | |
| 608 RawObject* const* from, | |
| 609 intptr_t count) { | |
| 610 ASSERT(Contains(reinterpret_cast<uword>(to))); | |
| 611 if (raw()->IsNewObject()) { | |
| 612 memmove(const_cast<RawObject**>(to), from, count * kWordSize); | |
| 613 } else { | |
| 614 for (intptr_t i = 0; i < count; ++i) { | |
| 615 StorePointer(&to[i], from[i]); | |
| 616 } | |
| 617 } | |
| 618 } | |
| 619 | |
| 596 // Use for storing into an explicitly Smi-typed field of an object | 620 // Use for storing into an explicitly Smi-typed field of an object |
| 597 // (i.e., both the previous and new value are Smis). | 621 // (i.e., both the previous and new value are Smis). |
| 598 void StoreSmi(RawSmi** addr, RawSmi* value) const { | 622 void StoreSmi(RawSmi* const* addr, RawSmi* value) const { |
| 599 // Can't use Contains, as array length is initialized through this method. | 623 // Can't use Contains, as array length is initialized through this method. |
| 600 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); | 624 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); |
| 601 *addr = value; | 625 *const_cast<RawSmi**>(addr) = value; |
| 626 } | |
| 627 | |
| 628 template<typename FieldType> | |
| 629 void StoreSimd128(const FieldType* addr, simd128_value_t value) const { | |
| 630 ASSERT(Contains(reinterpret_cast<uword>(addr))); | |
| 631 value.writeTo(const_cast<FieldType*>(addr)); | |
| 602 } | 632 } |
| 603 | 633 |
| 604 // Needs two template arguments to allow assigning enums to fixed-size ints. | 634 // Needs two template arguments to allow assigning enums to fixed-size ints. |
| 605 template<typename FieldType, typename ValueType> | 635 template<typename FieldType, typename ValueType> |
| 606 void StoreNonPointer(FieldType* addr, ValueType value) const { | 636 void StoreNonPointer(const FieldType* addr, ValueType value) const { |
| 607 // Can't use Contains, as it uses tags_, which is set through this method. | 637 // Can't use Contains, as it uses tags_, which is set through this method. |
| 608 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); | 638 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); |
| 609 *addr = value; | 639 *const_cast<FieldType*>(addr) = value; |
| 610 } | 640 } |
| 611 | 641 |
| 612 // Fail at link time if StoreNonPointer is called with an object pointer. | 642 // Provides non-const access to non-pointer fields within the object. Such |
| 643 // access does not need a write barrier, but it is *not* GC-safe (since the | |
| 644 // object might move), hence must be fully contained within a NoGCScope. | |
| 645 template<typename FieldType> | |
| 646 FieldType* UnsafeMutableNonPointer(const FieldType* addr) const { | |
| 647 // Allow pointers at the end of variable-length data, and disallow pointers | |
| 648 // within the header word. | |
| 649 ASSERT(Contains(reinterpret_cast<uword>(addr) - 1) && | |
| 650 Contains(reinterpret_cast<uword>(addr) - kWordSize)); | |
| 651 // At least check that there is a NoGCScope, and hope it's big enough. | |
| 652 ASSERT(Isolate::Current()->no_gc_scope_depth() > 0); | |
| 653 return const_cast<FieldType*>(addr); | |
| 654 } | |
| 655 | |
| 656 // Fail at link time if StoreNonPointer or UnsafeMutableNonPointer is | |
| 657 // instantiated with an object pointer type. | |
| 613 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ | 658 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ |
| 614 template<typename ValueType> \ | 659 template<typename ValueType> \ |
| 615 void StoreNonPointer(Raw##type** addr, ValueType value) const { \ | 660 void StoreNonPointer(Raw##type* const* addr, ValueType value) const { \ |
| 616 UnimplementedMethod(); \ | 661 UnimplementedMethod(); \ |
| 662 } \ | |
| 663 Raw##type** UnsafeMutableNonPointer(Raw##type* const* addr) const { \ | |
| 664 UnimplementedMethod(); \ | |
| 665 return NULL; \ | |
| 617 } | 666 } |
| 667 | |
| 618 CLASS_LIST(STORE_NON_POINTER_ILLEGAL_TYPE); | 668 CLASS_LIST(STORE_NON_POINTER_ILLEGAL_TYPE); |
| 619 void UnimplementedMethod() const; | 669 void UnimplementedMethod() const; |
| 620 #undef STORE_NON_POINTER_ILLEGAL_TYPE | 670 #undef STORE_NON_POINTER_ILLEGAL_TYPE |
| 621 | 671 |
| 672 // End of field mutator guards. | |
| 673 | |
| 622 RawObject* raw_; // The raw object reference. | 674 RawObject* raw_; // The raw object reference. |
| 623 | 675 |
| 624 protected: | 676 protected: |
| 625 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; | 677 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; |
| 626 | 678 |
| 627 private: | 679 private: |
| 628 static intptr_t NextFieldOffset() { | 680 static intptr_t NextFieldOffset() { |
| 629 // Indicates this class cannot be extended by dart code. | 681 // Indicates this class cannot be extended by dart code. |
| 630 return -kWordSize; | 682 return -kWordSize; |
| 631 } | 683 } |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1567 Error* bound_error) const; | 1619 Error* bound_error) const; |
| 1568 | 1620 |
| 1569 // Return the internal or public name of a subvector of this type argument | 1621 // Return the internal or public name of a subvector of this type argument |
| 1570 // vector, e.g. "<T, dynamic, List<T>, int>". | 1622 // vector, e.g. "<T, dynamic, List<T>, int>". |
| 1571 RawString* SubvectorName(intptr_t from_index, | 1623 RawString* SubvectorName(intptr_t from_index, |
| 1572 intptr_t len, | 1624 intptr_t len, |
| 1573 NameVisibility name_visibility) const; | 1625 NameVisibility name_visibility) const; |
| 1574 | 1626 |
| 1575 RawArray* instantiations() const; | 1627 RawArray* instantiations() const; |
| 1576 void set_instantiations(const Array& value) const; | 1628 void set_instantiations(const Array& value) const; |
| 1577 RawAbstractType** TypeAddr(intptr_t index) const; | 1629 RawAbstractType* const* TypeAddr(intptr_t index) const; |
| 1578 void SetLength(intptr_t value) const; | 1630 void SetLength(intptr_t value) const; |
| 1579 | 1631 |
| 1580 FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, Object); | 1632 FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, Object); |
| 1581 friend class AbstractType; | 1633 friend class AbstractType; |
| 1582 friend class Class; | 1634 friend class Class; |
| 1583 }; | 1635 }; |
| 1584 | 1636 |
| 1585 | 1637 |
| 1586 class PatchClass : public Object { | 1638 class PatchClass : public Object { |
| 1587 public: | 1639 public: |
| (...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3152 | 3204 |
| 3153 | 3205 |
| 3154 class PcDescriptors : public Object { | 3206 class PcDescriptors : public Object { |
| 3155 public: | 3207 public: |
| 3156 void AddDescriptor(intptr_t index, | 3208 void AddDescriptor(intptr_t index, |
| 3157 uword pc, | 3209 uword pc, |
| 3158 RawPcDescriptors::Kind kind, | 3210 RawPcDescriptors::Kind kind, |
| 3159 int64_t deopt_id, | 3211 int64_t deopt_id, |
| 3160 int64_t token_pos, // Or deopt reason. | 3212 int64_t token_pos, // Or deopt reason. |
| 3161 intptr_t try_index) const { // Or deopt index. | 3213 intptr_t try_index) const { // Or deopt index. |
| 3214 NoGCScope no_gc; | |
| 3162 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); | 3215 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); |
| 3163 rec->set_pc(pc); | 3216 rec->set_pc(pc); |
| 3164 rec->set_kind(kind); | 3217 rec->set_kind(kind); |
| 3165 ASSERT(Utils::IsInt(32, deopt_id)); | 3218 ASSERT(Utils::IsInt(32, deopt_id)); |
| 3166 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); | 3219 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); |
| 3167 ASSERT(Utils::IsInt(32, token_pos)); | 3220 ASSERT(Utils::IsInt(32, token_pos)); |
| 3168 rec->set_token_pos(static_cast<int32_t>(token_pos), | 3221 rec->set_token_pos(static_cast<int32_t>(token_pos), |
| 3169 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); | 3222 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); |
| 3170 ASSERT(Utils::IsInt(16, try_index)); | 3223 ASSERT(Utils::IsInt(16, try_index)); |
| 3171 rec->set_try_index(try_index); | 3224 rec->set_try_index(try_index); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3217 bool MoveNext() { | 3270 bool MoveNext() { |
| 3218 if (HasNext()) { | 3271 if (HasNext()) { |
| 3219 current_ix_ = next_ix_++; | 3272 current_ix_ = next_ix_++; |
| 3220 MoveToMatching(); | 3273 MoveToMatching(); |
| 3221 return true; | 3274 return true; |
| 3222 } else { | 3275 } else { |
| 3223 return false; | 3276 return false; |
| 3224 } | 3277 } |
| 3225 } | 3278 } |
| 3226 | 3279 |
| 3227 uword Pc() const { return descriptors_.recAt(current_ix_)->pc(); } | 3280 uword Pc() const { |
| 3281 NoGCScope no_gc; | |
| 3282 return descriptors_.recAt(current_ix_)->pc(); | |
| 3283 } | |
| 3228 intptr_t DeoptId() const { | 3284 intptr_t DeoptId() const { |
| 3285 NoGCScope no_gc; | |
| 3229 return descriptors_.recAt(current_ix_)->deopt_id(); | 3286 return descriptors_.recAt(current_ix_)->deopt_id(); |
| 3230 } | 3287 } |
| 3231 intptr_t TokenPos() const { | 3288 intptr_t TokenPos() const { |
| 3289 NoGCScope no_gc; | |
| 3232 return descriptors_.recAt(current_ix_)->token_pos(); | 3290 return descriptors_.recAt(current_ix_)->token_pos(); |
| 3233 } | 3291 } |
| 3234 intptr_t TryIndex() const { | 3292 intptr_t TryIndex() const { |
| 3293 NoGCScope no_gc; | |
| 3235 return descriptors_.recAt(current_ix_)->try_index(); | 3294 return descriptors_.recAt(current_ix_)->try_index(); |
| 3236 } | 3295 } |
| 3237 RawPcDescriptors::Kind Kind() const { | 3296 RawPcDescriptors::Kind Kind() const { |
| 3297 NoGCScope no_gc; | |
| 3238 return descriptors_.recAt(current_ix_)->kind(); | 3298 return descriptors_.recAt(current_ix_)->kind(); |
| 3239 } | 3299 } |
| 3240 | 3300 |
| 3241 private: | 3301 private: |
| 3242 friend class PcDescriptors; | 3302 friend class PcDescriptors; |
| 3243 | 3303 |
| 3244 bool HasNext() const { return next_ix_ < descriptors_.Length(); } | 3304 bool HasNext() const { return next_ix_ < descriptors_.Length(); } |
| 3245 | 3305 |
| 3246 // For nested iterations, starting at element after. | 3306 // For nested iterations, starting at element after. |
| 3247 explicit Iterator(const Iterator& iter) | 3307 explicit Iterator(const Iterator& iter) |
| 3248 : ValueObject(), | 3308 : ValueObject(), |
| 3249 descriptors_(iter.descriptors_), | 3309 descriptors_(iter.descriptors_), |
| 3250 kind_mask_(iter.kind_mask_), | 3310 kind_mask_(iter.kind_mask_), |
| 3251 next_ix_(iter.next_ix_), | 3311 next_ix_(iter.next_ix_), |
| 3252 current_ix_(iter.current_ix_) {} | 3312 current_ix_(iter.current_ix_) {} |
| 3253 | 3313 |
| 3254 // Moves to record that matches kind_mask_. | 3314 // Moves to record that matches kind_mask_. |
| 3255 void MoveToMatching() { | 3315 void MoveToMatching() { |
| 3316 NoGCScope no_gc; | |
| 3256 while (next_ix_ < descriptors_.Length()) { | 3317 while (next_ix_ < descriptors_.Length()) { |
| 3257 const RawPcDescriptors::PcDescriptorRec& rec = | 3318 const RawPcDescriptors::PcDescriptorRec& rec = |
| 3258 *descriptors_.recAt(next_ix_); | 3319 *descriptors_.recAt(next_ix_); |
| 3259 if ((rec.kind() & kind_mask_) != 0) { | 3320 if ((rec.kind() & kind_mask_) != 0) { |
| 3260 return; // Current is valid. | 3321 return; // Current is valid. |
| 3261 } else { | 3322 } else { |
| 3262 ++next_ix_; | 3323 ++next_ix_; |
| 3263 } | 3324 } |
| 3264 } | 3325 } |
| 3265 } | 3326 } |
| 3266 | 3327 |
| 3267 const PcDescriptors& descriptors_; | 3328 const PcDescriptors& descriptors_; |
| 3268 const intptr_t kind_mask_; | 3329 const intptr_t kind_mask_; |
| 3269 intptr_t next_ix_; | 3330 intptr_t next_ix_; |
| 3270 intptr_t current_ix_; | 3331 intptr_t current_ix_; |
| 3271 }; | 3332 }; |
| 3272 | 3333 |
| 3273 private: | 3334 private: |
| 3274 static const char* KindAsStr(RawPcDescriptors::Kind kind); | 3335 static const char* KindAsStr(RawPcDescriptors::Kind kind); |
| 3275 | 3336 |
| 3276 intptr_t Length() const; | 3337 intptr_t Length() const; |
| 3277 void SetLength(intptr_t value) const; | 3338 void SetLength(intptr_t value) const; |
| 3278 | 3339 |
| 3279 void SetRecordSizeInBytes(intptr_t value) const; | 3340 void SetRecordSizeInBytes(intptr_t value) const; |
| 3280 intptr_t RecordSizeInBytes() const; | 3341 intptr_t RecordSizeInBytes() const; |
| 3281 | 3342 |
| 3282 RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const { | 3343 RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const { |
| 3283 ASSERT((0 <= ix) && (ix < Length())); | 3344 ASSERT((0 <= ix) && (ix < Length())); |
| 3284 uint8_t* d = raw_ptr()->data() + (ix * RecordSizeInBytes()); | 3345 uint8_t* d = UnsafeMutableNonPointer(raw_ptr()->data()) + |
| 3346 (ix * RecordSizeInBytes()); | |
| 3285 return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d); | 3347 return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d); |
| 3286 } | 3348 } |
| 3287 | 3349 |
| 3288 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); | 3350 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); |
| 3289 friend class Class; | 3351 friend class Class; |
| 3290 friend class Object; | 3352 friend class Object; |
| 3291 }; | 3353 }; |
| 3292 | 3354 |
| 3293 | 3355 |
| 3294 class Stackmap : public Object { | 3356 class Stackmap : public Object { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3471 | 3533 |
| 3472 // Returns true iff decompression yields the same instructions as the | 3534 // Returns true iff decompression yields the same instructions as the |
| 3473 // original. | 3535 // original. |
| 3474 bool VerifyDecompression(const GrowableArray<DeoptInstr*>& original, | 3536 bool VerifyDecompression(const GrowableArray<DeoptInstr*>& original, |
| 3475 const Array& deopt_table) const; | 3537 const Array& deopt_table) const; |
| 3476 | 3538 |
| 3477 private: | 3539 private: |
| 3478 intptr_t* EntryAddr(intptr_t index, intptr_t entry_offset) const { | 3540 intptr_t* EntryAddr(intptr_t index, intptr_t entry_offset) const { |
| 3479 ASSERT((index >=0) && (index < Length())); | 3541 ASSERT((index >=0) && (index < Length())); |
| 3480 intptr_t data_index = (index * kNumberOfEntries) + entry_offset; | 3542 intptr_t data_index = (index * kNumberOfEntries) + entry_offset; |
| 3481 return &raw_ptr()->data()[data_index]; | 3543 return &UnsafeMutableNonPointer(raw_ptr()->data())[data_index]; |
| 3482 } | 3544 } |
| 3483 | 3545 |
| 3484 void SetLength(intptr_t value) const; | 3546 void SetLength(intptr_t value) const; |
| 3485 | 3547 |
| 3486 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object); | 3548 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object); |
| 3487 friend class Class; | 3549 friend class Class; |
| 3488 }; | 3550 }; |
| 3489 | 3551 |
| 3490 | 3552 |
| 3491 // Object holding information about an IC: test classes and their | 3553 // Object holding information about an IC: test classes and their |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3892 Assembler* assembler, | 3954 Assembler* assembler, |
| 3893 bool optimized = false); | 3955 bool optimized = false); |
| 3894 static RawCode* FinalizeCode(const char* name, | 3956 static RawCode* FinalizeCode(const char* name, |
| 3895 Assembler* assembler, | 3957 Assembler* assembler, |
| 3896 bool optimized = false); | 3958 bool optimized = false); |
| 3897 static RawCode* LookupCode(uword pc); | 3959 static RawCode* LookupCode(uword pc); |
| 3898 static RawCode* LookupCodeInVmIsolate(uword pc); | 3960 static RawCode* LookupCodeInVmIsolate(uword pc); |
| 3899 static RawCode* FindCode(uword pc, int64_t timestamp); | 3961 static RawCode* FindCode(uword pc, int64_t timestamp); |
| 3900 | 3962 |
| 3901 int32_t GetPointerOffsetAt(int index) const { | 3963 int32_t GetPointerOffsetAt(int index) const { |
| 3964 NoGCScope no_gc; | |
| 3902 return *PointerOffsetAddrAt(index); | 3965 return *PointerOffsetAddrAt(index); |
| 3903 } | 3966 } |
| 3904 intptr_t GetTokenIndexOfPC(uword pc) const; | 3967 intptr_t GetTokenIndexOfPC(uword pc) const; |
| 3905 | 3968 |
| 3906 enum { | 3969 enum { |
| 3907 kInvalidPc = -1 | 3970 kInvalidPc = -1 |
| 3908 }; | 3971 }; |
| 3909 | 3972 |
| 3910 // Returns 0 if code is not patchable | 3973 // Returns 0 if code is not patchable |
| 3911 uword GetEntryPatchPc() const; | 3974 uword GetEntryPatchPc() const; |
| 3912 uword GetPatchCodePc() const; | 3975 uword GetPatchCodePc() const; |
| 3913 | 3976 |
| 3914 uword GetLazyDeoptPc() const; | 3977 uword GetLazyDeoptPc() const; |
| 3915 | 3978 |
| 3916 // Find pc, return 0 if not found. | 3979 // Find pc, return 0 if not found. |
| 3917 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; | 3980 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; |
| 3918 intptr_t GetDeoptIdForOsr(uword pc) const; | 3981 intptr_t GetDeoptIdForOsr(uword pc) const; |
| 3919 | 3982 |
| 3920 RawString* Name() const; | 3983 RawString* Name() const; |
| 3921 RawString* PrettyName() const; | 3984 RawString* PrettyName() const; |
| 3922 | 3985 |
| 3923 int64_t compile_timestamp() const { | 3986 int64_t compile_timestamp() const { |
| 3924 return raw_ptr()->compile_timestamp_; | 3987 return raw_ptr()->compile_timestamp_; |
| 3925 } | 3988 } |
| 3926 | 3989 |
| 3927 intptr_t entry_patch_pc_offset() const { | 3990 intptr_t entry_patch_pc_offset() const { |
| 3928 return raw_ptr()->entry_patch_pc_offset_; | 3991 return raw_ptr()->entry_patch_pc_offset_; |
| 3929 } | 3992 } |
| 3930 void set_entry_patch_pc_offset(intptr_t pc) const { | 3993 void set_entry_patch_pc_offset(intptr_t pc) const { |
| 3931 raw_ptr()->entry_patch_pc_offset_ = pc; | 3994 StoreNonPointer(&raw_ptr()->entry_patch_pc_offset_, pc); |
| 3932 } | 3995 } |
| 3933 | 3996 |
| 3934 | 3997 |
| 3935 intptr_t patch_code_pc_offset() const { | 3998 intptr_t patch_code_pc_offset() const { |
| 3936 return raw_ptr()->patch_code_pc_offset_; | 3999 return raw_ptr()->patch_code_pc_offset_; |
| 3937 } | 4000 } |
| 3938 void set_patch_code_pc_offset(intptr_t pc) const { | 4001 void set_patch_code_pc_offset(intptr_t pc) const { |
| 3939 raw_ptr()->patch_code_pc_offset_ = pc; | 4002 StoreNonPointer(&raw_ptr()->patch_code_pc_offset_, pc); |
| 3940 } | 4003 } |
| 3941 | 4004 |
| 3942 | 4005 |
| 3943 intptr_t lazy_deopt_pc_offset() const { | 4006 intptr_t lazy_deopt_pc_offset() const { |
| 3944 return raw_ptr()->lazy_deopt_pc_offset_; | 4007 return raw_ptr()->lazy_deopt_pc_offset_; |
| 3945 } | 4008 } |
| 3946 void set_lazy_deopt_pc_offset(intptr_t pc) const { | 4009 void set_lazy_deopt_pc_offset(intptr_t pc) const { |
| 3947 raw_ptr()->lazy_deopt_pc_offset_ = pc; | 4010 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); |
| 3948 } | 4011 } |
| 3949 | 4012 |
| 3950 private: | 4013 private: |
| 3951 void set_state_bits(intptr_t bits) const; | 4014 void set_state_bits(intptr_t bits) const; |
| 3952 | 4015 |
| 3953 friend class RawObject; // For RawObject::SizeFromClass(). | 4016 friend class RawObject; // For RawObject::SizeFromClass(). |
| 3954 friend class RawCode; | 4017 friend class RawCode; |
| 3955 enum { | 4018 enum { |
| 3956 kOptimizedBit = 0, | 4019 kOptimizedBit = 0, |
| 3957 kAliveBit = 1, | 4020 kAliveBit = 1, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3995 | 4058 |
| 3996 void set_pointer_offsets_length(intptr_t value) { | 4059 void set_pointer_offsets_length(intptr_t value) { |
| 3997 // The number of fixups is limited to 1-billion. | 4060 // The number of fixups is limited to 1-billion. |
| 3998 ASSERT(Utils::IsUint(30, value)); | 4061 ASSERT(Utils::IsUint(30, value)); |
| 3999 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4062 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
| 4000 } | 4063 } |
| 4001 int32_t* PointerOffsetAddrAt(int index) const { | 4064 int32_t* PointerOffsetAddrAt(int index) const { |
| 4002 ASSERT(index >= 0); | 4065 ASSERT(index >= 0); |
| 4003 ASSERT(index < pointer_offsets_length()); | 4066 ASSERT(index < pointer_offsets_length()); |
| 4004 // TODO(iposva): Unit test is missing for this functionality. | 4067 // TODO(iposva): Unit test is missing for this functionality. |
| 4005 return &raw_ptr()->data()[index]; | 4068 return &UnsafeMutableNonPointer(raw_ptr()->data())[index]; |
| 4006 } | 4069 } |
| 4007 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { | 4070 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { |
| 4071 NoGCScope no_gc; | |
| 4008 *PointerOffsetAddrAt(index) = offset_in_instructions; | 4072 *PointerOffsetAddrAt(index) = offset_in_instructions; |
| 4009 } | 4073 } |
| 4010 | 4074 |
| 4011 intptr_t BinarySearchInSCallTable(uword pc) const; | 4075 intptr_t BinarySearchInSCallTable(uword pc) const; |
| 4012 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); | 4076 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); |
| 4013 | 4077 |
| 4014 // New is a private method as RawInstruction and RawCode objects should | 4078 // New is a private method as RawInstruction and RawCode objects should |
| 4015 // only be created using the Code::FinalizeCode method. This method creates | 4079 // only be created using the Code::FinalizeCode method. This method creates |
| 4016 // the RawInstruction and RawCode objects, sets up the pointer offsets | 4080 // the RawInstruction and RawCode objects, sets up the pointer offsets |
| 4017 // and links the two in a GC safe manner. | 4081 // and links the two in a GC safe manner. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4065 | 4129 |
| 4066 static intptr_t InstanceSize(intptr_t len) { | 4130 static intptr_t InstanceSize(intptr_t len) { |
| 4067 ASSERT(0 <= len && len <= kMaxElements); | 4131 ASSERT(0 <= len && len <= kMaxElements); |
| 4068 return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement)); | 4132 return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement)); |
| 4069 } | 4133 } |
| 4070 | 4134 |
| 4071 static RawContext* New(intptr_t num_variables, | 4135 static RawContext* New(intptr_t num_variables, |
| 4072 Heap::Space space = Heap::kNew); | 4136 Heap::Space space = Heap::kNew); |
| 4073 | 4137 |
| 4074 private: | 4138 private: |
| 4075 RawInstance** InstanceAddr(intptr_t context_index) const { | 4139 RawInstance* const* InstanceAddr(intptr_t context_index) const { |
| 4076 ASSERT((context_index >= 0) && (context_index < num_variables())); | 4140 ASSERT((context_index >= 0) && (context_index < num_variables())); |
| 4077 return &raw_ptr()->data()[context_index]; | 4141 return &raw_ptr()->data()[context_index]; |
| 4078 } | 4142 } |
| 4079 | 4143 |
| 4080 void set_isolate(Isolate* isolate) const { | 4144 void set_isolate(Isolate* isolate) const { |
| 4081 StoreNonPointer(&raw_ptr()->isolate_, isolate); | 4145 StoreNonPointer(&raw_ptr()->isolate_, isolate); |
| 4082 } | 4146 } |
| 4083 | 4147 |
| 4084 void set_num_variables(intptr_t num_variables) const { | 4148 void set_num_variables(intptr_t num_variables) const { |
| 4085 StoreNonPointer(&raw_ptr()->num_variables_, num_variables); | 4149 StoreNonPointer(&raw_ptr()->num_variables_, num_variables); |
| (...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5796 friend class ExternalOneByteString; | 5860 friend class ExternalOneByteString; |
| 5797 friend class ExternalTwoByteString; | 5861 friend class ExternalTwoByteString; |
| 5798 // So that the MarkingVisitor can print a debug string from a NoHandleScope. | 5862 // So that the MarkingVisitor can print a debug string from a NoHandleScope. |
| 5799 friend class MarkingVisitor; | 5863 friend class MarkingVisitor; |
| 5800 }; | 5864 }; |
| 5801 | 5865 |
| 5802 | 5866 |
| 5803 class OneByteString : public AllStatic { | 5867 class OneByteString : public AllStatic { |
| 5804 public: | 5868 public: |
| 5805 static uint16_t CharAt(const String& str, intptr_t index) { | 5869 static uint16_t CharAt(const String& str, intptr_t index) { |
| 5870 NoGCScope no_gc; | |
| 5806 return *CharAddr(str, index); | 5871 return *CharAddr(str, index); |
| 5807 } | 5872 } |
| 5808 | 5873 |
| 5809 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { | 5874 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { |
| 5875 NoGCScope no_gc; | |
| 5810 *CharAddr(str, index) = code_unit; | 5876 *CharAddr(str, index) = code_unit; |
| 5811 } | 5877 } |
| 5812 static RawOneByteString* EscapeSpecialCharacters(const String& str); | 5878 static RawOneByteString* EscapeSpecialCharacters(const String& str); |
| 5813 // We use the same maximum elements for all strings. | 5879 // We use the same maximum elements for all strings. |
| 5814 static const intptr_t kBytesPerElement = 1; | 5880 static const intptr_t kBytesPerElement = 1; |
| 5815 static const intptr_t kMaxElements = String::kMaxElements; | 5881 static const intptr_t kMaxElements = String::kMaxElements; |
| 5816 | 5882 |
| 5817 static intptr_t data_offset() { | 5883 static intptr_t data_offset() { |
| 5818 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); | 5884 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); |
| 5819 } | 5885 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5898 | 5964 |
| 5899 static RawOneByteString* null() { | 5965 static RawOneByteString* null() { |
| 5900 return reinterpret_cast<RawOneByteString*>(Object::null()); | 5966 return reinterpret_cast<RawOneByteString*>(Object::null()); |
| 5901 } | 5967 } |
| 5902 | 5968 |
| 5903 private: | 5969 private: |
| 5904 static RawOneByteString* raw(const String& str) { | 5970 static RawOneByteString* raw(const String& str) { |
| 5905 return reinterpret_cast<RawOneByteString*>(str.raw()); | 5971 return reinterpret_cast<RawOneByteString*>(str.raw()); |
| 5906 } | 5972 } |
| 5907 | 5973 |
| 5908 static RawOneByteString* raw_ptr(const String& str) { | 5974 static const RawOneByteString* raw_ptr(const String& str) { |
| 5909 return reinterpret_cast<RawOneByteString*>(str.raw_ptr()); | 5975 return reinterpret_cast<const RawOneByteString*>(str.raw_ptr()); |
| 5910 } | 5976 } |
| 5911 | 5977 |
| 5912 static uint8_t* CharAddr(const String& str, intptr_t index) { | 5978 static uint8_t* CharAddr(const String& str, intptr_t index) { |
| 5913 ASSERT((index >= 0) && (index < str.Length())); | 5979 ASSERT((index >= 0) && (index < str.Length())); |
| 5914 ASSERT(str.IsOneByteString()); | 5980 ASSERT(str.IsOneByteString()); |
| 5915 NoGCScope no_gc; | 5981 return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[index]; |
| 5916 return &raw_ptr(str)->data()[index]; | |
| 5917 } | 5982 } |
| 5918 | 5983 |
| 5919 static RawOneByteString* ReadFrom(SnapshotReader* reader, | 5984 static RawOneByteString* ReadFrom(SnapshotReader* reader, |
| 5920 intptr_t object_id, | 5985 intptr_t object_id, |
| 5921 intptr_t tags, | 5986 intptr_t tags, |
| 5922 Snapshot::Kind kind); | 5987 Snapshot::Kind kind); |
| 5923 | 5988 |
| 5924 friend class Class; | 5989 friend class Class; |
| 5925 friend class String; | 5990 friend class String; |
| 5926 friend class ExternalOneByteString; | 5991 friend class ExternalOneByteString; |
| 5927 friend class SnapshotReader; | 5992 friend class SnapshotReader; |
| 5928 friend class StringHasher; | 5993 friend class StringHasher; |
| 5929 }; | 5994 }; |
| 5930 | 5995 |
| 5931 | 5996 |
| 5932 class TwoByteString : public AllStatic { | 5997 class TwoByteString : public AllStatic { |
| 5933 public: | 5998 public: |
| 5934 static uint16_t CharAt(const String& str, intptr_t index) { | 5999 static uint16_t CharAt(const String& str, intptr_t index) { |
| 6000 NoGCScope no_gc; | |
| 5935 return *CharAddr(str, index); | 6001 return *CharAddr(str, index); |
| 5936 } | 6002 } |
| 5937 | 6003 |
| 5938 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { | 6004 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { |
| 6005 NoGCScope no_gc; | |
| 5939 *CharAddr(str, index) = ch; | 6006 *CharAddr(str, index) = ch; |
| 5940 } | 6007 } |
| 5941 | 6008 |
| 5942 static RawTwoByteString* EscapeSpecialCharacters(const String& str); | 6009 static RawTwoByteString* EscapeSpecialCharacters(const String& str); |
| 5943 | 6010 |
| 5944 // We use the same maximum elements for all strings. | 6011 // We use the same maximum elements for all strings. |
| 5945 static const intptr_t kBytesPerElement = 2; | 6012 static const intptr_t kBytesPerElement = 2; |
| 5946 static const intptr_t kMaxElements = String::kMaxElements; | 6013 static const intptr_t kMaxElements = String::kMaxElements; |
| 5947 | 6014 |
| 5948 static intptr_t data_offset() { | 6015 static intptr_t data_offset() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6000 } | 6067 } |
| 6001 | 6068 |
| 6002 | 6069 |
| 6003 static const ClassId kClassId = kTwoByteStringCid; | 6070 static const ClassId kClassId = kTwoByteStringCid; |
| 6004 | 6071 |
| 6005 private: | 6072 private: |
| 6006 static RawTwoByteString* raw(const String& str) { | 6073 static RawTwoByteString* raw(const String& str) { |
| 6007 return reinterpret_cast<RawTwoByteString*>(str.raw()); | 6074 return reinterpret_cast<RawTwoByteString*>(str.raw()); |
| 6008 } | 6075 } |
| 6009 | 6076 |
| 6010 static RawTwoByteString* raw_ptr(const String& str) { | 6077 static const RawTwoByteString* raw_ptr(const String& str) { |
| 6011 return reinterpret_cast<RawTwoByteString*>(str.raw_ptr()); | 6078 return reinterpret_cast<const RawTwoByteString*>(str.raw_ptr()); |
| 6012 } | 6079 } |
| 6013 | 6080 |
| 6014 static uint16_t* CharAddr(const String& str, intptr_t index) { | 6081 static uint16_t* CharAddr(const String& str, intptr_t index) { |
| 6015 ASSERT((index >= 0) && (index < str.Length())); | 6082 ASSERT((index >= 0) && (index < str.Length())); |
| 6016 ASSERT(str.IsTwoByteString()); | 6083 ASSERT(str.IsTwoByteString()); |
| 6017 NoGCScope no_gc; | 6084 return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[index]; |
| 6018 return &raw_ptr(str)->data()[index]; | |
| 6019 } | 6085 } |
| 6020 | 6086 |
| 6021 static RawTwoByteString* ReadFrom(SnapshotReader* reader, | 6087 static RawTwoByteString* ReadFrom(SnapshotReader* reader, |
| 6022 intptr_t object_id, | 6088 intptr_t object_id, |
| 6023 intptr_t tags, | 6089 intptr_t tags, |
| 6024 Snapshot::Kind kind); | 6090 Snapshot::Kind kind); |
| 6025 | 6091 |
| 6026 friend class Class; | 6092 friend class Class; |
| 6027 friend class String; | 6093 friend class String; |
| 6028 friend class SnapshotReader; | 6094 friend class SnapshotReader; |
| 6029 }; | 6095 }; |
| 6030 | 6096 |
| 6031 | 6097 |
| 6032 class ExternalOneByteString : public AllStatic { | 6098 class ExternalOneByteString : public AllStatic { |
| 6033 public: | 6099 public: |
| 6034 static uint16_t CharAt(const String& str, intptr_t index) { | 6100 static uint16_t CharAt(const String& str, intptr_t index) { |
| 6101 NoGCScope no_gc; | |
| 6035 return *CharAddr(str, index); | 6102 return *CharAddr(str, index); |
| 6036 } | 6103 } |
| 6037 | 6104 |
| 6038 static void* GetPeer(const String& str) { | 6105 static void* GetPeer(const String& str) { |
| 6039 return raw_ptr(str)->external_data_->peer(); | 6106 return raw_ptr(str)->external_data_->peer(); |
| 6040 } | 6107 } |
| 6041 | 6108 |
| 6042 // We use the same maximum elements for all strings. | 6109 // We use the same maximum elements for all strings. |
| 6043 static const intptr_t kBytesPerElement = 1; | 6110 static const intptr_t kBytesPerElement = 1; |
| 6044 static const intptr_t kMaxElements = String::kMaxElements; | 6111 static const intptr_t kMaxElements = String::kMaxElements; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 6061 static RawOneByteString* EncodeIRI(const String& str); | 6128 static RawOneByteString* EncodeIRI(const String& str); |
| 6062 static RawOneByteString* DecodeIRI(const String& str); | 6129 static RawOneByteString* DecodeIRI(const String& str); |
| 6063 | 6130 |
| 6064 static const ClassId kClassId = kExternalOneByteStringCid; | 6131 static const ClassId kClassId = kExternalOneByteStringCid; |
| 6065 | 6132 |
| 6066 private: | 6133 private: |
| 6067 static RawExternalOneByteString* raw(const String& str) { | 6134 static RawExternalOneByteString* raw(const String& str) { |
| 6068 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); | 6135 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); |
| 6069 } | 6136 } |
| 6070 | 6137 |
| 6071 static RawExternalOneByteString* raw_ptr(const String& str) { | 6138 static const RawExternalOneByteString* raw_ptr(const String& str) { |
| 6072 return reinterpret_cast<RawExternalOneByteString*>(str.raw_ptr()); | 6139 return reinterpret_cast<const RawExternalOneByteString*>(str.raw_ptr()); |
| 6073 } | 6140 } |
| 6074 | 6141 |
| 6075 static const uint8_t* CharAddr(const String& str, intptr_t index) { | 6142 static const uint8_t* CharAddr(const String& str, intptr_t index) { |
| 6076 ASSERT((index >= 0) && (index < str.Length())); | 6143 ASSERT((index >= 0) && (index < str.Length())); |
| 6077 ASSERT(str.IsExternalOneByteString()); | 6144 ASSERT(str.IsExternalOneByteString()); |
| 6078 NoGCScope no_gc; | |
| 6079 return &(raw_ptr(str)->external_data_->data()[index]); | 6145 return &(raw_ptr(str)->external_data_->data()[index]); |
| 6080 } | 6146 } |
| 6081 | 6147 |
| 6082 static void SetExternalData(const String& str, | 6148 static void SetExternalData(const String& str, |
| 6083 ExternalStringData<uint8_t>* data) { | 6149 ExternalStringData<uint8_t>* data) { |
| 6084 ASSERT(str.IsExternalOneByteString()); | 6150 ASSERT(str.IsExternalOneByteString()); |
| 6085 NoGCScope no_gc; | |
| 6086 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); | 6151 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); |
| 6087 } | 6152 } |
| 6088 | 6153 |
| 6089 static void Finalize(void* isolate_callback_data, | 6154 static void Finalize(void* isolate_callback_data, |
| 6090 Dart_WeakPersistentHandle handle, | 6155 Dart_WeakPersistentHandle handle, |
| 6091 void* peer); | 6156 void* peer); |
| 6092 | 6157 |
| 6093 static RawExternalOneByteString* ReadFrom(SnapshotReader* reader, | 6158 static RawExternalOneByteString* ReadFrom(SnapshotReader* reader, |
| 6094 intptr_t object_id, | 6159 intptr_t object_id, |
| 6095 intptr_t tags, | 6160 intptr_t tags, |
| 6096 Snapshot::Kind kind); | 6161 Snapshot::Kind kind); |
| 6097 | 6162 |
| 6098 static intptr_t NextFieldOffset() { | 6163 static intptr_t NextFieldOffset() { |
| 6099 // Indicates this class cannot be extended by dart code. | 6164 // Indicates this class cannot be extended by dart code. |
| 6100 return -kWordSize; | 6165 return -kWordSize; |
| 6101 } | 6166 } |
| 6102 | 6167 |
| 6103 friend class Class; | 6168 friend class Class; |
| 6104 friend class String; | 6169 friend class String; |
| 6105 friend class SnapshotReader; | 6170 friend class SnapshotReader; |
| 6106 }; | 6171 }; |
| 6107 | 6172 |
| 6108 | 6173 |
| 6109 class ExternalTwoByteString : public AllStatic { | 6174 class ExternalTwoByteString : public AllStatic { |
| 6110 public: | 6175 public: |
| 6111 static uint16_t CharAt(const String& str, intptr_t index) { | 6176 static uint16_t CharAt(const String& str, intptr_t index) { |
| 6177 NoGCScope no_gc; | |
| 6112 return *CharAddr(str, index); | 6178 return *CharAddr(str, index); |
| 6113 } | 6179 } |
| 6114 | 6180 |
| 6115 static void* GetPeer(const String& str) { | 6181 static void* GetPeer(const String& str) { |
| 6116 return raw_ptr(str)->external_data_->peer(); | 6182 return raw_ptr(str)->external_data_->peer(); |
| 6117 } | 6183 } |
| 6118 | 6184 |
| 6119 // We use the same maximum elements for all strings. | 6185 // We use the same maximum elements for all strings. |
| 6120 static const intptr_t kBytesPerElement = 2; | 6186 static const intptr_t kBytesPerElement = 2; |
| 6121 static const intptr_t kMaxElements = String::kMaxElements; | 6187 static const intptr_t kMaxElements = String::kMaxElements; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 6134 return reinterpret_cast<RawExternalTwoByteString*>(Object::null()); | 6200 return reinterpret_cast<RawExternalTwoByteString*>(Object::null()); |
| 6135 } | 6201 } |
| 6136 | 6202 |
| 6137 static const ClassId kClassId = kExternalTwoByteStringCid; | 6203 static const ClassId kClassId = kExternalTwoByteStringCid; |
| 6138 | 6204 |
| 6139 private: | 6205 private: |
| 6140 static RawExternalTwoByteString* raw(const String& str) { | 6206 static RawExternalTwoByteString* raw(const String& str) { |
| 6141 return reinterpret_cast<RawExternalTwoByteString*>(str.raw()); | 6207 return reinterpret_cast<RawExternalTwoByteString*>(str.raw()); |
| 6142 } | 6208 } |
| 6143 | 6209 |
| 6144 static RawExternalTwoByteString* raw_ptr(const String& str) { | 6210 static const RawExternalTwoByteString* raw_ptr(const String& str) { |
| 6145 return reinterpret_cast<RawExternalTwoByteString*>(str.raw_ptr()); | 6211 return reinterpret_cast<const RawExternalTwoByteString*>(str.raw_ptr()); |
| 6146 } | 6212 } |
| 6147 | 6213 |
| 6148 static const uint16_t* CharAddr(const String& str, intptr_t index) { | 6214 static const uint16_t* CharAddr(const String& str, intptr_t index) { |
| 6149 ASSERT((index >= 0) && (index < str.Length())); | 6215 ASSERT((index >= 0) && (index < str.Length())); |
| 6150 ASSERT(str.IsExternalTwoByteString()); | 6216 ASSERT(str.IsExternalTwoByteString()); |
| 6151 NoGCScope no_gc; | |
| 6152 return &(raw_ptr(str)->external_data_->data()[index]); | 6217 return &(raw_ptr(str)->external_data_->data()[index]); |
| 6153 } | 6218 } |
| 6154 | 6219 |
| 6155 static void SetExternalData(const String& str, | 6220 static void SetExternalData(const String& str, |
| 6156 ExternalStringData<uint16_t>* data) { | 6221 ExternalStringData<uint16_t>* data) { |
| 6157 ASSERT(str.IsExternalTwoByteString()); | 6222 ASSERT(str.IsExternalTwoByteString()); |
| 6158 NoGCScope no_gc; | |
| 6159 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); | 6223 str.StoreNonPointer(&raw_ptr(str)->external_data_, data); |
| 6160 } | 6224 } |
| 6161 | 6225 |
| 6162 static void Finalize(void* isolate_callback_data, | 6226 static void Finalize(void* isolate_callback_data, |
| 6163 Dart_WeakPersistentHandle handle, | 6227 Dart_WeakPersistentHandle handle, |
| 6164 void* peer); | 6228 void* peer); |
| 6165 | 6229 |
| 6166 static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader, | 6230 static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader, |
| 6167 intptr_t object_id, | 6231 intptr_t object_id, |
| 6168 intptr_t tags, | 6232 intptr_t tags, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6303 RawArray* Slice(intptr_t start, | 6367 RawArray* Slice(intptr_t start, |
| 6304 intptr_t count, | 6368 intptr_t count, |
| 6305 bool with_type_argument) const; | 6369 bool with_type_argument) const; |
| 6306 | 6370 |
| 6307 protected: | 6371 protected: |
| 6308 static RawArray* New(intptr_t class_id, | 6372 static RawArray* New(intptr_t class_id, |
| 6309 intptr_t len, | 6373 intptr_t len, |
| 6310 Heap::Space space = Heap::kNew); | 6374 Heap::Space space = Heap::kNew); |
| 6311 | 6375 |
| 6312 private: | 6376 private: |
| 6313 RawObject** ObjectAddr(intptr_t index) const { | 6377 RawObject* const* ObjectAddr(intptr_t index) const { |
| 6314 // TODO(iposva): Determine if we should throw an exception here. | 6378 // TODO(iposva): Determine if we should throw an exception here. |
| 6315 ASSERT((index >= 0) && (index < Length())); | 6379 ASSERT((index >= 0) && (index < Length())); |
| 6316 return &raw_ptr()->data()[index]; | 6380 return &raw_ptr()->data()[index]; |
| 6317 } | 6381 } |
| 6318 | 6382 |
| 6319 void SetLength(intptr_t value) const { | 6383 void SetLength(intptr_t value) const { |
| 6320 // This is only safe because we create a new Smi, which does not cause | 6384 // This is only safe because we create a new Smi, which does not cause |
| 6321 // heap allocation. | 6385 // heap allocation. |
| 6322 StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 6386 StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
| 6323 } | 6387 } |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6643 } | 6707 } |
| 6644 | 6708 |
| 6645 intptr_t LengthInBytes() const { | 6709 intptr_t LengthInBytes() const { |
| 6646 intptr_t cid = raw()->GetClassId(); | 6710 intptr_t cid = raw()->GetClassId(); |
| 6647 return (ElementSizeInBytes(cid) * Length()); | 6711 return (ElementSizeInBytes(cid) * Length()); |
| 6648 } | 6712 } |
| 6649 | 6713 |
| 6650 void* DataAddr(intptr_t byte_offset) const { | 6714 void* DataAddr(intptr_t byte_offset) const { |
| 6651 ASSERT((byte_offset == 0) || | 6715 ASSERT((byte_offset == 0) || |
| 6652 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); | 6716 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); |
| 6653 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset); | 6717 return reinterpret_cast<void*>( |
| 6718 UnsafeMutableNonPointer(raw_ptr()->data()) + byte_offset); | |
| 6654 } | 6719 } |
| 6655 | 6720 |
| 6656 virtual bool CanonicalizeEquals(const Instance& other) const; | 6721 virtual bool CanonicalizeEquals(const Instance& other) const; |
| 6657 | 6722 |
| 6658 #define TYPED_GETTER_SETTER(name, type) \ | 6723 #define TYPED_GETTER_SETTER(name, type) \ |
| 6659 type Get##name(intptr_t byte_offset) const { \ | 6724 type Get##name(intptr_t byte_offset) const { \ |
| 6725 NoGCScope no_gc; \ | |
| 6660 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ | 6726 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ |
| 6661 } \ | 6727 } \ |
| 6662 void Set##name(intptr_t byte_offset, type value) const { \ | 6728 void Set##name(intptr_t byte_offset, type value) const { \ |
| 6729 NoGCScope no_gc; \ | |
| 6663 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ | 6730 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ |
| 6664 } | 6731 } |
| 6665 TYPED_GETTER_SETTER(Int8, int8_t) | 6732 TYPED_GETTER_SETTER(Int8, int8_t) |
| 6666 TYPED_GETTER_SETTER(Uint8, uint8_t) | 6733 TYPED_GETTER_SETTER(Uint8, uint8_t) |
| 6667 TYPED_GETTER_SETTER(Int16, int16_t) | 6734 TYPED_GETTER_SETTER(Int16, int16_t) |
| 6668 TYPED_GETTER_SETTER(Uint16, uint16_t) | 6735 TYPED_GETTER_SETTER(Uint16, uint16_t) |
| 6669 TYPED_GETTER_SETTER(Int32, int32_t) | 6736 TYPED_GETTER_SETTER(Int32, int32_t) |
| 6670 TYPED_GETTER_SETTER(Uint32, uint32_t) | 6737 TYPED_GETTER_SETTER(Uint32, uint32_t) |
| 6671 TYPED_GETTER_SETTER(Int64, int64_t) | 6738 TYPED_GETTER_SETTER(Int64, int64_t) |
| 6672 TYPED_GETTER_SETTER(Uint64, uint64_t) | 6739 TYPED_GETTER_SETTER(Uint64, uint64_t) |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6900 class TypedDataView : public AllStatic { | 6967 class TypedDataView : public AllStatic { |
| 6901 public: | 6968 public: |
| 6902 static intptr_t ElementSizeInBytes(const Instance& view_obj) { | 6969 static intptr_t ElementSizeInBytes(const Instance& view_obj) { |
| 6903 ASSERT(!view_obj.IsNull()); | 6970 ASSERT(!view_obj.IsNull()); |
| 6904 intptr_t cid = view_obj.raw()->GetClassId(); | 6971 intptr_t cid = view_obj.raw()->GetClassId(); |
| 6905 return ElementSizeInBytes(cid); | 6972 return ElementSizeInBytes(cid); |
| 6906 } | 6973 } |
| 6907 | 6974 |
| 6908 static RawInstance* Data(const Instance& view_obj) { | 6975 static RawInstance* Data(const Instance& view_obj) { |
| 6909 ASSERT(!view_obj.IsNull()); | 6976 ASSERT(!view_obj.IsNull()); |
| 6910 return *reinterpret_cast<RawInstance**>(view_obj.raw_ptr() + kDataOffset); | 6977 return *reinterpret_cast<RawInstance* const*>( |
| 6978 view_obj.raw_ptr() + kDataOffset); | |
| 6911 } | 6979 } |
| 6912 | 6980 |
| 6913 static RawSmi* OffsetInBytes(const Instance& view_obj) { | 6981 static RawSmi* OffsetInBytes(const Instance& view_obj) { |
| 6914 ASSERT(!view_obj.IsNull()); | 6982 ASSERT(!view_obj.IsNull()); |
| 6915 return *reinterpret_cast<RawSmi**>( | 6983 return *reinterpret_cast<RawSmi* const*>( |
| 6916 view_obj.raw_ptr() + kOffsetInBytesOffset); | 6984 view_obj.raw_ptr() + kOffsetInBytesOffset); |
| 6917 } | 6985 } |
| 6918 | 6986 |
| 6919 static RawSmi* Length(const Instance& view_obj) { | 6987 static RawSmi* Length(const Instance& view_obj) { |
| 6920 ASSERT(!view_obj.IsNull()); | 6988 ASSERT(!view_obj.IsNull()); |
| 6921 return *reinterpret_cast<RawSmi**>(view_obj.raw_ptr() + kLengthOffset); | 6989 return *reinterpret_cast<RawSmi* const*>( |
| 6990 view_obj.raw_ptr() + kLengthOffset); | |
| 6922 } | 6991 } |
| 6923 | 6992 |
| 6924 static bool IsExternalTypedDataView(const Instance& view_obj) { | 6993 static bool IsExternalTypedDataView(const Instance& view_obj) { |
| 6925 const Instance& data = Instance::Handle(Data(view_obj)); | 6994 const Instance& data = Instance::Handle(Data(view_obj)); |
| 6926 intptr_t cid = data.raw()->GetClassId(); | 6995 intptr_t cid = data.raw()->GetClassId(); |
| 6927 ASSERT(RawObject::IsTypedDataClassId(cid) || | 6996 ASSERT(RawObject::IsTypedDataClassId(cid) || |
| 6928 RawObject::IsExternalTypedDataClassId(cid)); | 6997 RawObject::IsExternalTypedDataClassId(cid)); |
| 6929 return RawObject::IsExternalTypedDataClassId(cid); | 6998 return RawObject::IsExternalTypedDataClassId(cid); |
| 6930 } | 6999 } |
| 6931 | 7000 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 6958 kOffsetInBytesOffset = 2, | 7027 kOffsetInBytesOffset = 2, |
| 6959 kLengthOffset = 3, | 7028 kLengthOffset = 3, |
| 6960 }; | 7029 }; |
| 6961 }; | 7030 }; |
| 6962 | 7031 |
| 6963 | 7032 |
| 6964 class ByteBuffer : public AllStatic { | 7033 class ByteBuffer : public AllStatic { |
| 6965 public: | 7034 public: |
| 6966 static RawInstance* Data(const Instance& view_obj) { | 7035 static RawInstance* Data(const Instance& view_obj) { |
| 6967 ASSERT(!view_obj.IsNull()); | 7036 ASSERT(!view_obj.IsNull()); |
| 6968 return *reinterpret_cast<RawInstance**>(view_obj.raw_ptr() + kDataOffset); | 7037 return *reinterpret_cast<RawInstance* const*>( |
| 7038 view_obj.raw_ptr() + kDataOffset); | |
| 6969 } | 7039 } |
| 6970 | 7040 |
| 6971 static intptr_t NumberOfFields() { | 7041 static intptr_t NumberOfFields() { |
| 6972 return kDataOffset; | 7042 return kDataOffset; |
| 6973 } | 7043 } |
| 6974 | 7044 |
| 6975 static intptr_t data_offset() { | 7045 static intptr_t data_offset() { |
| 6976 return kWordSize * kDataOffset; | 7046 return kWordSize * kDataOffset; |
| 6977 } | 7047 } |
| 6978 | 7048 |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7513 | 7583 |
| 7514 | 7584 |
| 7515 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7585 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
| 7516 intptr_t index) { | 7586 intptr_t index) { |
| 7517 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7587 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
| 7518 } | 7588 } |
| 7519 | 7589 |
| 7520 } // namespace dart | 7590 } // namespace dart |
| 7521 | 7591 |
| 7522 #endif // VM_OBJECT_H_ | 7592 #endif // VM_OBJECT_H_ |
| OLD | NEW |