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

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

Issue 612133004: Write barrier audit: const raw_ptr() (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698