OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 | 652 |
653 // Needs two template arguments to allow assigning enums to fixed-size ints. | 653 // Needs two template arguments to allow assigning enums to fixed-size ints. |
654 template<typename FieldType, typename ValueType> | 654 template<typename FieldType, typename ValueType> |
655 void StoreNonPointer(const FieldType* addr, ValueType value) const { | 655 void StoreNonPointer(const FieldType* addr, ValueType value) const { |
656 // Can't use Contains, as it uses tags_, which is set through this method. | 656 // Can't use Contains, as it uses tags_, which is set through this method. |
657 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); | 657 ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw())); |
658 *const_cast<FieldType*>(addr) = value; | 658 *const_cast<FieldType*>(addr) = value; |
659 } | 659 } |
660 | 660 |
661 // Provides non-const access to non-pointer fields within the object. Such | 661 // Provides non-const access to non-pointer fields within the object. Such |
662 // access does not need a write barrier, but it is *not* GC-safe (since the | 662 // access does not need a write barrier, but it is *not* GC-safe, since the |
663 // object might move), hence must be fully contained within a NoGCScope. | 663 // object might move, hence must be fully contained within a NoSafepointScope. |
664 template<typename FieldType> | 664 template<typename FieldType> |
665 FieldType* UnsafeMutableNonPointer(const FieldType* addr) const { | 665 FieldType* UnsafeMutableNonPointer(const FieldType* addr) const { |
666 // Allow pointers at the end of variable-length data, and disallow pointers | 666 // Allow pointers at the end of variable-length data, and disallow pointers |
667 // within the header word. | 667 // within the header word. |
668 ASSERT(Contains(reinterpret_cast<uword>(addr) - 1) && | 668 ASSERT(Contains(reinterpret_cast<uword>(addr) - 1) && |
669 Contains(reinterpret_cast<uword>(addr) - kWordSize)); | 669 Contains(reinterpret_cast<uword>(addr) - kWordSize)); |
670 // At least check that there is a NoGCScope, and hope it's big enough. | 670 // At least check that there is a NoSafepointScope and hope it's big enough. |
671 ASSERT(Isolate::Current()->no_gc_scope_depth() > 0); | 671 ASSERT(Isolate::Current()->no_safepoint_scope_depth() > 0); |
672 return const_cast<FieldType*>(addr); | 672 return const_cast<FieldType*>(addr); |
673 } | 673 } |
674 | 674 |
675 // Fail at link time if StoreNonPointer or UnsafeMutableNonPointer is | 675 // Fail at link time if StoreNonPointer or UnsafeMutableNonPointer is |
676 // instantiated with an object pointer type. | 676 // instantiated with an object pointer type. |
677 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ | 677 #define STORE_NON_POINTER_ILLEGAL_TYPE(type) \ |
678 template<typename ValueType> \ | 678 template<typename ValueType> \ |
679 void StoreNonPointer(Raw##type* const* addr, ValueType value) const { \ | 679 void StoreNonPointer(Raw##type* const* addr, ValueType value) const { \ |
680 UnimplementedMethod(); \ | 680 UnimplementedMethod(); \ |
681 } \ | 681 } \ |
(...skipping 2592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3274 | 3274 |
3275 | 3275 |
3276 class PcDescriptors : public Object { | 3276 class PcDescriptors : public Object { |
3277 public: | 3277 public: |
3278 void AddDescriptor(intptr_t index, | 3278 void AddDescriptor(intptr_t index, |
3279 uword pc_offset, | 3279 uword pc_offset, |
3280 RawPcDescriptors::Kind kind, | 3280 RawPcDescriptors::Kind kind, |
3281 int64_t deopt_id, | 3281 int64_t deopt_id, |
3282 int64_t token_pos, // Or deopt reason. | 3282 int64_t token_pos, // Or deopt reason. |
3283 intptr_t try_index) const { // Or deopt index. | 3283 intptr_t try_index) const { // Or deopt index. |
3284 NoGCScope no_gc; | 3284 NoSafepointScope no_safepoint; |
3285 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); | 3285 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); |
3286 rec->set_pc_offset(pc_offset); | 3286 rec->set_pc_offset(pc_offset); |
3287 rec->set_kind(kind); | 3287 rec->set_kind(kind); |
3288 ASSERT(Utils::IsInt(32, deopt_id)); | 3288 ASSERT(Utils::IsInt(32, deopt_id)); |
3289 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); | 3289 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); |
3290 ASSERT(Utils::IsInt(32, token_pos)); | 3290 ASSERT(Utils::IsInt(32, token_pos)); |
3291 rec->set_token_pos(static_cast<int32_t>(token_pos), | 3291 rec->set_token_pos(static_cast<int32_t>(token_pos), |
3292 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); | 3292 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); |
3293 ASSERT(Utils::IsInt(16, try_index)); | 3293 ASSERT(Utils::IsInt(16, try_index)); |
3294 rec->set_try_index(try_index); | 3294 rec->set_try_index(try_index); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3338 if (HasNext()) { | 3338 if (HasNext()) { |
3339 current_ix_ = next_ix_++; | 3339 current_ix_ = next_ix_++; |
3340 MoveToMatching(); | 3340 MoveToMatching(); |
3341 return true; | 3341 return true; |
3342 } else { | 3342 } else { |
3343 return false; | 3343 return false; |
3344 } | 3344 } |
3345 } | 3345 } |
3346 | 3346 |
3347 uword PcOffset() const { | 3347 uword PcOffset() const { |
3348 NoGCScope no_gc; | 3348 NoSafepointScope no_safepoint; |
3349 return descriptors_.recAt(current_ix_)->pc_offset(); | 3349 return descriptors_.recAt(current_ix_)->pc_offset(); |
3350 } | 3350 } |
3351 intptr_t DeoptId() const { | 3351 intptr_t DeoptId() const { |
3352 NoGCScope no_gc; | 3352 NoSafepointScope no_safepoint; |
3353 return descriptors_.recAt(current_ix_)->deopt_id(); | 3353 return descriptors_.recAt(current_ix_)->deopt_id(); |
3354 } | 3354 } |
3355 intptr_t TokenPos() const { | 3355 intptr_t TokenPos() const { |
3356 NoGCScope no_gc; | 3356 NoSafepointScope no_safepoint; |
3357 return descriptors_.recAt(current_ix_)->token_pos(); | 3357 return descriptors_.recAt(current_ix_)->token_pos(); |
3358 } | 3358 } |
3359 intptr_t TryIndex() const { | 3359 intptr_t TryIndex() const { |
3360 NoGCScope no_gc; | 3360 NoSafepointScope no_safepoint; |
3361 return descriptors_.recAt(current_ix_)->try_index(); | 3361 return descriptors_.recAt(current_ix_)->try_index(); |
3362 } | 3362 } |
3363 RawPcDescriptors::Kind Kind() const { | 3363 RawPcDescriptors::Kind Kind() const { |
3364 NoGCScope no_gc; | 3364 NoSafepointScope no_safepoint; |
3365 return descriptors_.recAt(current_ix_)->kind(); | 3365 return descriptors_.recAt(current_ix_)->kind(); |
3366 } | 3366 } |
3367 | 3367 |
3368 private: | 3368 private: |
3369 friend class PcDescriptors; | 3369 friend class PcDescriptors; |
3370 | 3370 |
3371 bool HasNext() const { return next_ix_ < descriptors_.Length(); } | 3371 bool HasNext() const { return next_ix_ < descriptors_.Length(); } |
3372 | 3372 |
3373 // For nested iterations, starting at element after. | 3373 // For nested iterations, starting at element after. |
3374 explicit Iterator(const Iterator& iter) | 3374 explicit Iterator(const Iterator& iter) |
3375 : ValueObject(), | 3375 : ValueObject(), |
3376 descriptors_(iter.descriptors_), | 3376 descriptors_(iter.descriptors_), |
3377 kind_mask_(iter.kind_mask_), | 3377 kind_mask_(iter.kind_mask_), |
3378 next_ix_(iter.next_ix_), | 3378 next_ix_(iter.next_ix_), |
3379 current_ix_(iter.current_ix_) {} | 3379 current_ix_(iter.current_ix_) {} |
3380 | 3380 |
3381 // Moves to record that matches kind_mask_. | 3381 // Moves to record that matches kind_mask_. |
3382 void MoveToMatching() { | 3382 void MoveToMatching() { |
3383 NoGCScope no_gc; | 3383 NoSafepointScope no_safepoint; |
3384 while (next_ix_ < descriptors_.Length()) { | 3384 while (next_ix_ < descriptors_.Length()) { |
3385 const RawPcDescriptors::PcDescriptorRec& rec = | 3385 const RawPcDescriptors::PcDescriptorRec& rec = |
3386 *descriptors_.recAt(next_ix_); | 3386 *descriptors_.recAt(next_ix_); |
3387 if ((rec.kind() & kind_mask_) != 0) { | 3387 if ((rec.kind() & kind_mask_) != 0) { |
3388 return; // Current is valid. | 3388 return; // Current is valid. |
3389 } else { | 3389 } else { |
3390 ++next_ix_; | 3390 ++next_ix_; |
3391 } | 3391 } |
3392 } | 3392 } |
3393 } | 3393 } |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4137 Assembler* assembler, | 4137 Assembler* assembler, |
4138 bool optimized = false); | 4138 bool optimized = false); |
4139 static RawCode* FinalizeCode(const char* name, | 4139 static RawCode* FinalizeCode(const char* name, |
4140 Assembler* assembler, | 4140 Assembler* assembler, |
4141 bool optimized = false); | 4141 bool optimized = false); |
4142 static RawCode* LookupCode(uword pc); | 4142 static RawCode* LookupCode(uword pc); |
4143 static RawCode* LookupCodeInVmIsolate(uword pc); | 4143 static RawCode* LookupCodeInVmIsolate(uword pc); |
4144 static RawCode* FindCode(uword pc, int64_t timestamp); | 4144 static RawCode* FindCode(uword pc, int64_t timestamp); |
4145 | 4145 |
4146 int32_t GetPointerOffsetAt(int index) const { | 4146 int32_t GetPointerOffsetAt(int index) const { |
4147 NoGCScope no_gc; | 4147 NoSafepointScope no_safepoint; |
4148 return *PointerOffsetAddrAt(index); | 4148 return *PointerOffsetAddrAt(index); |
4149 } | 4149 } |
4150 intptr_t GetTokenIndexOfPC(uword pc) const; | 4150 intptr_t GetTokenIndexOfPC(uword pc) const; |
4151 | 4151 |
4152 enum { | 4152 enum { |
4153 kInvalidPc = -1 | 4153 kInvalidPc = -1 |
4154 }; | 4154 }; |
4155 | 4155 |
4156 // Returns 0 if code is not patchable | 4156 // Returns 0 if code is not patchable |
4157 uword GetEntryPatchPc() const; | 4157 uword GetEntryPatchPc() const; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4248 ASSERT(Utils::IsUint(30, value)); | 4248 ASSERT(Utils::IsUint(30, value)); |
4249 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4249 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
4250 } | 4250 } |
4251 int32_t* PointerOffsetAddrAt(int index) const { | 4251 int32_t* PointerOffsetAddrAt(int index) const { |
4252 ASSERT(index >= 0); | 4252 ASSERT(index >= 0); |
4253 ASSERT(index < pointer_offsets_length()); | 4253 ASSERT(index < pointer_offsets_length()); |
4254 // TODO(iposva): Unit test is missing for this functionality. | 4254 // TODO(iposva): Unit test is missing for this functionality. |
4255 return &UnsafeMutableNonPointer(raw_ptr()->data())[index]; | 4255 return &UnsafeMutableNonPointer(raw_ptr()->data())[index]; |
4256 } | 4256 } |
4257 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { | 4257 void SetPointerOffsetAt(int index, int32_t offset_in_instructions) { |
4258 NoGCScope no_gc; | 4258 NoSafepointScope no_safepoint; |
4259 *PointerOffsetAddrAt(index) = offset_in_instructions; | 4259 *PointerOffsetAddrAt(index) = offset_in_instructions; |
4260 } | 4260 } |
4261 | 4261 |
4262 // Currently slow, as it searches linearly through inlined_intervals(). | 4262 // Currently slow, as it searches linearly through inlined_intervals(). |
4263 intptr_t GetCallerId(intptr_t inlined_id) const; | 4263 intptr_t GetCallerId(intptr_t inlined_id) const; |
4264 | 4264 |
4265 intptr_t BinarySearchInSCallTable(uword pc) const; | 4265 intptr_t BinarySearchInSCallTable(uword pc) const; |
4266 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); | 4266 static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc); |
4267 | 4267 |
4268 // New is a private method as RawInstruction and RawCode objects should | 4268 // New is a private method as RawInstruction and RawCode objects should |
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6069 | 6069 |
6070 class OneByteString : public AllStatic { | 6070 class OneByteString : public AllStatic { |
6071 public: | 6071 public: |
6072 static uint16_t CharAt(const String& str, intptr_t index) { | 6072 static uint16_t CharAt(const String& str, intptr_t index) { |
6073 ASSERT((index >= 0) && (index < str.Length())); | 6073 ASSERT((index >= 0) && (index < str.Length())); |
6074 ASSERT(str.IsOneByteString()); | 6074 ASSERT(str.IsOneByteString()); |
6075 return raw_ptr(str)->data()[index]; | 6075 return raw_ptr(str)->data()[index]; |
6076 } | 6076 } |
6077 | 6077 |
6078 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { | 6078 static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) { |
6079 NoGCScope no_gc; | 6079 NoSafepointScope no_safepoint; |
6080 *CharAddr(str, index) = code_unit; | 6080 *CharAddr(str, index) = code_unit; |
6081 } | 6081 } |
6082 static RawOneByteString* EscapeSpecialCharacters(const String& str); | 6082 static RawOneByteString* EscapeSpecialCharacters(const String& str); |
6083 // We use the same maximum elements for all strings. | 6083 // We use the same maximum elements for all strings. |
6084 static const intptr_t kBytesPerElement = 1; | 6084 static const intptr_t kBytesPerElement = 1; |
6085 static const intptr_t kMaxElements = String::kMaxElements; | 6085 static const intptr_t kMaxElements = String::kMaxElements; |
6086 | 6086 |
6087 static intptr_t data_offset() { | 6087 static intptr_t data_offset() { |
6088 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); | 6088 return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data); |
6089 } | 6089 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6200 | 6200 |
6201 class TwoByteString : public AllStatic { | 6201 class TwoByteString : public AllStatic { |
6202 public: | 6202 public: |
6203 static uint16_t CharAt(const String& str, intptr_t index) { | 6203 static uint16_t CharAt(const String& str, intptr_t index) { |
6204 ASSERT((index >= 0) && (index < str.Length())); | 6204 ASSERT((index >= 0) && (index < str.Length())); |
6205 ASSERT(str.IsTwoByteString()); | 6205 ASSERT(str.IsTwoByteString()); |
6206 return raw_ptr(str)->data()[index]; | 6206 return raw_ptr(str)->data()[index]; |
6207 } | 6207 } |
6208 | 6208 |
6209 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { | 6209 static void SetCharAt(const String& str, intptr_t index, uint16_t ch) { |
6210 NoGCScope no_gc; | 6210 NoSafepointScope no_safepoint; |
6211 *CharAddr(str, index) = ch; | 6211 *CharAddr(str, index) = ch; |
6212 } | 6212 } |
6213 | 6213 |
6214 static RawTwoByteString* EscapeSpecialCharacters(const String& str); | 6214 static RawTwoByteString* EscapeSpecialCharacters(const String& str); |
6215 | 6215 |
6216 // We use the same maximum elements for all strings. | 6216 // We use the same maximum elements for all strings. |
6217 static const intptr_t kBytesPerElement = 2; | 6217 static const intptr_t kBytesPerElement = 2; |
6218 static const intptr_t kMaxElements = String::kMaxElements; | 6218 static const intptr_t kMaxElements = String::kMaxElements; |
6219 | 6219 |
6220 static intptr_t data_offset() { | 6220 static intptr_t data_offset() { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6306 | 6306 |
6307 friend class Class; | 6307 friend class Class; |
6308 friend class String; | 6308 friend class String; |
6309 friend class SnapshotReader; | 6309 friend class SnapshotReader; |
6310 }; | 6310 }; |
6311 | 6311 |
6312 | 6312 |
6313 class ExternalOneByteString : public AllStatic { | 6313 class ExternalOneByteString : public AllStatic { |
6314 public: | 6314 public: |
6315 static uint16_t CharAt(const String& str, intptr_t index) { | 6315 static uint16_t CharAt(const String& str, intptr_t index) { |
6316 NoGCScope no_gc; | 6316 NoSafepointScope no_safepoint; |
6317 return *CharAddr(str, index); | 6317 return *CharAddr(str, index); |
6318 } | 6318 } |
6319 | 6319 |
6320 static void* GetPeer(const String& str) { | 6320 static void* GetPeer(const String& str) { |
6321 return raw_ptr(str)->external_data_->peer(); | 6321 return raw_ptr(str)->external_data_->peer(); |
6322 } | 6322 } |
6323 | 6323 |
6324 static intptr_t external_data_offset() { | 6324 static intptr_t external_data_offset() { |
6325 return OFFSET_OF(RawExternalOneByteString, external_data_); | 6325 return OFFSET_OF(RawExternalOneByteString, external_data_); |
6326 } | 6326 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6386 | 6386 |
6387 friend class Class; | 6387 friend class Class; |
6388 friend class String; | 6388 friend class String; |
6389 friend class SnapshotReader; | 6389 friend class SnapshotReader; |
6390 }; | 6390 }; |
6391 | 6391 |
6392 | 6392 |
6393 class ExternalTwoByteString : public AllStatic { | 6393 class ExternalTwoByteString : public AllStatic { |
6394 public: | 6394 public: |
6395 static uint16_t CharAt(const String& str, intptr_t index) { | 6395 static uint16_t CharAt(const String& str, intptr_t index) { |
6396 NoGCScope no_gc; | 6396 NoSafepointScope no_safepoint; |
6397 return *CharAddr(str, index); | 6397 return *CharAddr(str, index); |
6398 } | 6398 } |
6399 | 6399 |
6400 static void* GetPeer(const String& str) { | 6400 static void* GetPeer(const String& str) { |
6401 return raw_ptr(str)->external_data_->peer(); | 6401 return raw_ptr(str)->external_data_->peer(); |
6402 } | 6402 } |
6403 | 6403 |
6404 static intptr_t external_data_offset() { | 6404 static intptr_t external_data_offset() { |
6405 return OFFSET_OF(RawExternalTwoByteString, external_data_); | 6405 return OFFSET_OF(RawExternalTwoByteString, external_data_); |
6406 } | 6406 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6514 return OFFSET_OF_RETURNED_VALUE(RawArray, data); | 6514 return OFFSET_OF_RETURNED_VALUE(RawArray, data); |
6515 } | 6515 } |
6516 static intptr_t element_offset(intptr_t index) { | 6516 static intptr_t element_offset(intptr_t index) { |
6517 return OFFSET_OF_RETURNED_VALUE(RawArray, data) + kWordSize * index; | 6517 return OFFSET_OF_RETURNED_VALUE(RawArray, data) + kWordSize * index; |
6518 } | 6518 } |
6519 | 6519 |
6520 RawObject* At(intptr_t index) const { | 6520 RawObject* At(intptr_t index) const { |
6521 return *ObjectAddr(index); | 6521 return *ObjectAddr(index); |
6522 } | 6522 } |
6523 void SetAt(intptr_t index, const Object& value) const { | 6523 void SetAt(intptr_t index, const Object& value) const { |
6524 // TODO(iposva): Add storing NoGCScope. | 6524 // TODO(iposva): Add storing NoSafepointScope. |
6525 StorePointer(ObjectAddr(index), value.raw()); | 6525 StorePointer(ObjectAddr(index), value.raw()); |
6526 } | 6526 } |
6527 | 6527 |
6528 bool IsImmutable() const { | 6528 bool IsImmutable() const { |
6529 return raw()->GetClassId() == kImmutableArrayCid; | 6529 return raw()->GetClassId() == kImmutableArrayCid; |
6530 } | 6530 } |
6531 | 6531 |
6532 virtual RawTypeArguments* GetTypeArguments() const { | 6532 virtual RawTypeArguments* GetTypeArguments() const { |
6533 return raw_ptr()->type_arguments_; | 6533 return raw_ptr()->type_arguments_; |
6534 } | 6534 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6646 return reinterpret_cast<RawImmutableArray*>(array.raw()); | 6646 return reinterpret_cast<RawImmutableArray*>(array.raw()); |
6647 } | 6647 } |
6648 | 6648 |
6649 friend class Class; | 6649 friend class Class; |
6650 }; | 6650 }; |
6651 | 6651 |
6652 | 6652 |
6653 class GrowableObjectArray : public Instance { | 6653 class GrowableObjectArray : public Instance { |
6654 public: | 6654 public: |
6655 intptr_t Capacity() const { | 6655 intptr_t Capacity() const { |
6656 NoGCScope no_gc; | 6656 NoSafepointScope no_safepoint; |
6657 ASSERT(!IsNull()); | 6657 ASSERT(!IsNull()); |
6658 return Smi::Value(DataArray()->length_); | 6658 return Smi::Value(DataArray()->length_); |
6659 } | 6659 } |
6660 intptr_t Length() const { | 6660 intptr_t Length() const { |
6661 ASSERT(!IsNull()); | 6661 ASSERT(!IsNull()); |
6662 return Smi::Value(raw_ptr()->length_); | 6662 return Smi::Value(raw_ptr()->length_); |
6663 } | 6663 } |
6664 void SetLength(intptr_t value) const { | 6664 void SetLength(intptr_t value) const { |
6665 // This is only safe because we create a new Smi, which does not cause | 6665 // This is only safe because we create a new Smi, which does not cause |
6666 // heap allocation. | 6666 // heap allocation. |
6667 StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 6667 StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
6668 } | 6668 } |
6669 | 6669 |
6670 RawArray* data() const { return raw_ptr()->data_; } | 6670 RawArray* data() const { return raw_ptr()->data_; } |
6671 void SetData(const Array& value) const { | 6671 void SetData(const Array& value) const { |
6672 StorePointer(&raw_ptr()->data_, value.raw()); | 6672 StorePointer(&raw_ptr()->data_, value.raw()); |
6673 } | 6673 } |
6674 | 6674 |
6675 RawObject* At(intptr_t index) const { | 6675 RawObject* At(intptr_t index) const { |
6676 NoGCScope no_gc; | 6676 NoSafepointScope no_safepoint; |
6677 ASSERT(!IsNull()); | 6677 ASSERT(!IsNull()); |
6678 ASSERT(index < Length()); | 6678 ASSERT(index < Length()); |
6679 return *ObjectAddr(index); | 6679 return *ObjectAddr(index); |
6680 } | 6680 } |
6681 void SetAt(intptr_t index, const Object& value) const { | 6681 void SetAt(intptr_t index, const Object& value) const { |
6682 ASSERT(!IsNull()); | 6682 ASSERT(!IsNull()); |
6683 ASSERT(index < Length()); | 6683 ASSERT(index < Length()); |
6684 | 6684 |
6685 // TODO(iposva): Add storing NoGCScope. | 6685 // TODO(iposva): Add storing NoSafepointScope. |
6686 DataStorePointer(ObjectAddr(index), value.raw()); | 6686 DataStorePointer(ObjectAddr(index), value.raw()); |
6687 } | 6687 } |
6688 | 6688 |
6689 void Add(const Object& value, Heap::Space space = Heap::kNew) const; | 6689 void Add(const Object& value, Heap::Space space = Heap::kNew) const; |
6690 | 6690 |
6691 void Grow(intptr_t new_capacity, Heap::Space space = Heap::kNew) const; | 6691 void Grow(intptr_t new_capacity, Heap::Space space = Heap::kNew) const; |
6692 RawObject* RemoveLast() const; | 6692 RawObject* RemoveLast() const; |
6693 | 6693 |
6694 virtual RawTypeArguments* GetTypeArguments() const { | 6694 virtual RawTypeArguments* GetTypeArguments() const { |
6695 return raw_ptr()->type_arguments_; | 6695 return raw_ptr()->type_arguments_; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6924 ASSERT((byte_offset == 0) || | 6924 ASSERT((byte_offset == 0) || |
6925 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); | 6925 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); |
6926 return reinterpret_cast<void*>( | 6926 return reinterpret_cast<void*>( |
6927 UnsafeMutableNonPointer(raw_ptr()->data()) + byte_offset); | 6927 UnsafeMutableNonPointer(raw_ptr()->data()) + byte_offset); |
6928 } | 6928 } |
6929 | 6929 |
6930 virtual bool CanonicalizeEquals(const Instance& other) const; | 6930 virtual bool CanonicalizeEquals(const Instance& other) const; |
6931 | 6931 |
6932 #define TYPED_GETTER_SETTER(name, type) \ | 6932 #define TYPED_GETTER_SETTER(name, type) \ |
6933 type Get##name(intptr_t byte_offset) const { \ | 6933 type Get##name(intptr_t byte_offset) const { \ |
6934 NoGCScope no_gc; \ | 6934 NoSafepointScope no_safepoint; \ |
6935 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ | 6935 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ |
6936 } \ | 6936 } \ |
6937 void Set##name(intptr_t byte_offset, type value) const { \ | 6937 void Set##name(intptr_t byte_offset, type value) const { \ |
6938 NoGCScope no_gc; \ | 6938 NoSafepointScope no_safepoint; \ |
6939 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ | 6939 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ |
6940 } | 6940 } |
6941 TYPED_GETTER_SETTER(Int8, int8_t) | 6941 TYPED_GETTER_SETTER(Int8, int8_t) |
6942 TYPED_GETTER_SETTER(Uint8, uint8_t) | 6942 TYPED_GETTER_SETTER(Uint8, uint8_t) |
6943 TYPED_GETTER_SETTER(Int16, int16_t) | 6943 TYPED_GETTER_SETTER(Int16, int16_t) |
6944 TYPED_GETTER_SETTER(Uint16, uint16_t) | 6944 TYPED_GETTER_SETTER(Uint16, uint16_t) |
6945 TYPED_GETTER_SETTER(Int32, int32_t) | 6945 TYPED_GETTER_SETTER(Int32, int32_t) |
6946 TYPED_GETTER_SETTER(Uint32, uint32_t) | 6946 TYPED_GETTER_SETTER(Uint32, uint32_t) |
6947 TYPED_GETTER_SETTER(Int64, int64_t) | 6947 TYPED_GETTER_SETTER(Int64, int64_t) |
6948 TYPED_GETTER_SETTER(Uint64, uint64_t) | 6948 TYPED_GETTER_SETTER(Uint64, uint64_t) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6997 static void Copy(const DstType& dst, intptr_t dst_offset_in_bytes, | 6997 static void Copy(const DstType& dst, intptr_t dst_offset_in_bytes, |
6998 const SrcType& src, intptr_t src_offset_in_bytes, | 6998 const SrcType& src, intptr_t src_offset_in_bytes, |
6999 intptr_t length_in_bytes) { | 6999 intptr_t length_in_bytes) { |
7000 ASSERT(Utils::RangeCheck(src_offset_in_bytes, | 7000 ASSERT(Utils::RangeCheck(src_offset_in_bytes, |
7001 length_in_bytes, | 7001 length_in_bytes, |
7002 src.LengthInBytes())); | 7002 src.LengthInBytes())); |
7003 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, | 7003 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, |
7004 length_in_bytes, | 7004 length_in_bytes, |
7005 dst.LengthInBytes())); | 7005 dst.LengthInBytes())); |
7006 { | 7006 { |
7007 NoGCScope no_gc; | 7007 NoSafepointScope no_safepoint; |
7008 if (length_in_bytes > 0) { | 7008 if (length_in_bytes > 0) { |
7009 memmove(dst.DataAddr(dst_offset_in_bytes), | 7009 memmove(dst.DataAddr(dst_offset_in_bytes), |
7010 src.DataAddr(src_offset_in_bytes), | 7010 src.DataAddr(src_offset_in_bytes), |
7011 length_in_bytes); | 7011 length_in_bytes); |
7012 } | 7012 } |
7013 } | 7013 } |
7014 } | 7014 } |
7015 | 7015 |
7016 | 7016 |
7017 template <typename DstType, typename SrcType> | 7017 template <typename DstType, typename SrcType> |
7018 static void ClampedCopy(const DstType& dst, intptr_t dst_offset_in_bytes, | 7018 static void ClampedCopy(const DstType& dst, intptr_t dst_offset_in_bytes, |
7019 const SrcType& src, intptr_t src_offset_in_bytes, | 7019 const SrcType& src, intptr_t src_offset_in_bytes, |
7020 intptr_t length_in_bytes) { | 7020 intptr_t length_in_bytes) { |
7021 ASSERT(Utils::RangeCheck(src_offset_in_bytes, | 7021 ASSERT(Utils::RangeCheck(src_offset_in_bytes, |
7022 length_in_bytes, | 7022 length_in_bytes, |
7023 src.LengthInBytes())); | 7023 src.LengthInBytes())); |
7024 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, | 7024 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, |
7025 length_in_bytes, | 7025 length_in_bytes, |
7026 dst.LengthInBytes())); | 7026 dst.LengthInBytes())); |
7027 { | 7027 { |
7028 NoGCScope no_gc; | 7028 NoSafepointScope no_safepoint; |
7029 if (length_in_bytes > 0) { | 7029 if (length_in_bytes > 0) { |
7030 uint8_t* dst_data = | 7030 uint8_t* dst_data = |
7031 reinterpret_cast<uint8_t*>(dst.DataAddr(dst_offset_in_bytes)); | 7031 reinterpret_cast<uint8_t*>(dst.DataAddr(dst_offset_in_bytes)); |
7032 int8_t* src_data = | 7032 int8_t* src_data = |
7033 reinterpret_cast<int8_t*>(src.DataAddr(src_offset_in_bytes)); | 7033 reinterpret_cast<int8_t*>(src.DataAddr(src_offset_in_bytes)); |
7034 for (intptr_t ix = 0; ix < length_in_bytes; ix++) { | 7034 for (intptr_t ix = 0; ix < length_in_bytes; ix++) { |
7035 int8_t v = *src_data; | 7035 int8_t v = *src_data; |
7036 if (v < 0) v = 0; | 7036 if (v < 0) v = 0; |
7037 *dst_data = v; | 7037 *dst_data = v; |
7038 src_data++; | 7038 src_data++; |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7748 } | 7748 } |
7749 | 7749 |
7750 | 7750 |
7751 void Context::SetAt(intptr_t index, const Object& value) const { | 7751 void Context::SetAt(intptr_t index, const Object& value) const { |
7752 StorePointer(ObjectAddr(index), value.raw()); | 7752 StorePointer(ObjectAddr(index), value.raw()); |
7753 } | 7753 } |
7754 | 7754 |
7755 | 7755 |
7756 intptr_t Instance::GetNativeField(int index) const { | 7756 intptr_t Instance::GetNativeField(int index) const { |
7757 ASSERT(IsValidNativeIndex(index)); | 7757 ASSERT(IsValidNativeIndex(index)); |
7758 NoGCScope no_gc; | 7758 NoSafepointScope no_safepoint; |
7759 RawTypedData* native_fields = | 7759 RawTypedData* native_fields = |
7760 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); | 7760 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); |
7761 if (native_fields == TypedData::null()) { | 7761 if (native_fields == TypedData::null()) { |
7762 return 0; | 7762 return 0; |
7763 } | 7763 } |
7764 return reinterpret_cast<intptr_t*>(native_fields->ptr()->data())[index]; | 7764 return reinterpret_cast<intptr_t*>(native_fields->ptr()->data())[index]; |
7765 } | 7765 } |
7766 | 7766 |
7767 | 7767 |
7768 void Instance::GetNativeFields(uint16_t num_fields, | 7768 void Instance::GetNativeFields(uint16_t num_fields, |
7769 intptr_t* field_values) const { | 7769 intptr_t* field_values) const { |
7770 NoGCScope no_gc; | 7770 NoSafepointScope no_safepoint; |
7771 ASSERT(num_fields == NumNativeFields()); | 7771 ASSERT(num_fields == NumNativeFields()); |
7772 ASSERT(field_values != NULL); | 7772 ASSERT(field_values != NULL); |
7773 RawTypedData* native_fields = | 7773 RawTypedData* native_fields = |
7774 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); | 7774 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); |
7775 if (native_fields == TypedData::null()) { | 7775 if (native_fields == TypedData::null()) { |
7776 for (intptr_t i = 0; i < num_fields; i++) { | 7776 for (intptr_t i = 0; i < num_fields; i++) { |
7777 field_values[i] = 0; | 7777 field_values[i] = 0; |
7778 } | 7778 } |
7779 } | 7779 } |
7780 intptr_t* fields = reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); | 7780 intptr_t* fields = reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7836 | 7836 |
7837 | 7837 |
7838 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7838 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
7839 intptr_t index) { | 7839 intptr_t index) { |
7840 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7840 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
7841 } | 7841 } |
7842 | 7842 |
7843 } // namespace dart | 7843 } // namespace dart |
7844 | 7844 |
7845 #endif // VM_OBJECT_H_ | 7845 #endif // VM_OBJECT_H_ |
OLD | NEW |