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

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') | runtime/vm/raw_object.h » ('J')
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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | runtime/vm/raw_object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698