| 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 3256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3267 | 3267 |
| 3268 private: | 3268 private: |
| 3269 FINAL_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors, Object); | 3269 FINAL_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors, Object); |
| 3270 friend class Class; | 3270 friend class Class; |
| 3271 friend class Object; | 3271 friend class Object; |
| 3272 }; | 3272 }; |
| 3273 | 3273 |
| 3274 | 3274 |
| 3275 class PcDescriptors : public Object { | 3275 class PcDescriptors : public Object { |
| 3276 public: | 3276 public: |
| 3277 void AddDescriptor(intptr_t index, | 3277 static const intptr_t kBytesPerElement = 1; |
| 3278 uword pc_offset, | 3278 static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement; |
| 3279 RawPcDescriptors::Kind kind, | |
| 3280 int64_t deopt_id, | |
| 3281 int64_t token_pos, // Or deopt reason. | |
| 3282 intptr_t try_index) const { // Or deopt index. | |
| 3283 NoSafepointScope no_safepoint; | |
| 3284 RawPcDescriptors::PcDescriptorRec* rec = recAt(index); | |
| 3285 rec->set_pc_offset(pc_offset); | |
| 3286 rec->set_kind(kind); | |
| 3287 ASSERT(Utils::IsInt(32, deopt_id)); | |
| 3288 rec->set_deopt_id(static_cast<int32_t>(deopt_id)); | |
| 3289 ASSERT(Utils::IsInt(32, token_pos)); | |
| 3290 rec->set_token_pos(static_cast<int32_t>(token_pos), | |
| 3291 RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize); | |
| 3292 ASSERT(Utils::IsInt(16, try_index)); | |
| 3293 rec->set_try_index(try_index); | |
| 3294 ASSERT(rec->try_index() == try_index); | |
| 3295 ASSERT(rec->token_pos() == token_pos); | |
| 3296 } | |
| 3297 | |
| 3298 static const intptr_t kMaxBytesPerElement = | |
| 3299 sizeof(RawPcDescriptors::PcDescriptorRec); | |
| 3300 static const intptr_t kMaxElements = kMaxInt32 / kMaxBytesPerElement; | |
| 3301 | 3279 |
| 3302 static intptr_t InstanceSize() { | 3280 static intptr_t InstanceSize() { |
| 3303 ASSERT(sizeof(RawPcDescriptors) == | 3281 ASSERT(sizeof(RawPcDescriptors) == |
| 3304 OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data)); | 3282 OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data)); |
| 3305 return 0; | 3283 return 0; |
| 3306 } | 3284 } |
| 3307 static intptr_t InstanceSize(intptr_t len, intptr_t record_size_in_bytes) { | 3285 static intptr_t InstanceSize(intptr_t len) { |
| 3308 ASSERT(0 <= len && len <= kMaxElements); | 3286 ASSERT(0 <= len && len <= kMaxElements); |
| 3309 return RoundedAllocationSize( | 3287 return RoundedAllocationSize(sizeof(RawPcDescriptors) + len); |
| 3310 sizeof(RawPcDescriptors) + (len * record_size_in_bytes)); | |
| 3311 } | 3288 } |
| 3312 | 3289 |
| 3313 static RawPcDescriptors* New(intptr_t num_descriptors, bool has_try_index); | 3290 static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data); |
| 3314 | 3291 |
| 3315 // Verify (assert) assumptions about pc descriptors in debug mode. | 3292 // Verify (assert) assumptions about pc descriptors in debug mode. |
| 3316 void Verify(const Function& function) const; | 3293 void Verify(const Function& function) const; |
| 3317 | 3294 |
| 3318 static void PrintHeaderString(); | 3295 static void PrintHeaderString(); |
| 3319 | 3296 |
| 3320 void PrintToJSONObject(JSONObject* jsobj, bool ref) const; | 3297 void PrintToJSONObject(JSONObject* jsobj, bool ref) const; |
| 3321 | 3298 |
| 3299 // Encode integer in SLEB128 format. |
| 3300 static void EncodeInteger(GrowableArray<uint8_t>* data, intptr_t value); |
| 3301 |
| 3302 // Decode SLEB128 encoded integer. Update byte_index to the next integer. |
| 3303 intptr_t DecodeInteger(intptr_t* byte_index) const; |
| 3304 |
| 3322 // We would have a VisitPointers function here to traverse the | 3305 // We would have a VisitPointers function here to traverse the |
| 3323 // pc descriptors table to visit objects if any in the table. | 3306 // pc descriptors table to visit objects if any in the table. |
| 3324 // Note: never return a reference to a RawPcDescriptors::PcDescriptorRec | 3307 // Note: never return a reference to a RawPcDescriptors::PcDescriptorRec |
| 3325 // as the object can move. | 3308 // as the object can move. |
| 3326 class Iterator : ValueObject { | 3309 class Iterator : ValueObject { |
| 3327 public: | 3310 public: |
| 3328 Iterator(const PcDescriptors& descriptors, intptr_t kind_mask) | 3311 Iterator(const PcDescriptors& descriptors, intptr_t kind_mask) |
| 3329 : descriptors_(descriptors), | 3312 : descriptors_(descriptors), |
| 3330 kind_mask_(kind_mask), | 3313 kind_mask_(kind_mask), |
| 3331 next_ix_(0), | 3314 byte_index_(0), |
| 3332 current_ix_(-1) { | 3315 cur_pc_offset_(0), |
| 3333 MoveToMatching(); | 3316 cur_kind_(0), |
| 3317 cur_deopt_id_(0), |
| 3318 cur_token_pos_(0), |
| 3319 cur_try_index_(0) { |
| 3334 } | 3320 } |
| 3335 | 3321 |
| 3336 bool MoveNext() { | 3322 bool MoveNext() { |
| 3337 if (HasNext()) { | 3323 // Moves to record that matches kind_mask_. |
| 3338 current_ix_ = next_ix_++; | 3324 while (byte_index_ < descriptors_.Length()) { |
| 3339 MoveToMatching(); | 3325 int32_t merged_kind_try = descriptors_.DecodeInteger(&byte_index_); |
| 3340 return true; | 3326 cur_kind_ = |
| 3341 } else { | 3327 RawPcDescriptors::MergedKindTry::DecodeKind(merged_kind_try); |
| 3342 return false; | 3328 cur_try_index_ = |
| 3329 RawPcDescriptors::MergedKindTry::DecodeTryIndex(merged_kind_try); |
| 3330 |
| 3331 cur_pc_offset_ += descriptors_.DecodeInteger(&byte_index_); |
| 3332 cur_deopt_id_ += descriptors_.DecodeInteger(&byte_index_); |
| 3333 cur_token_pos_ += descriptors_.DecodeInteger(&byte_index_); |
| 3334 |
| 3335 if ((cur_kind_ & kind_mask_) != 0) { |
| 3336 return true; // Current is valid. |
| 3337 } |
| 3343 } | 3338 } |
| 3339 return false; |
| 3344 } | 3340 } |
| 3345 | 3341 |
| 3346 uword PcOffset() const { | 3342 uword PcOffset() const { return cur_pc_offset_; } |
| 3347 NoSafepointScope no_safepoint; | 3343 intptr_t DeoptId() const { return cur_deopt_id_; } |
| 3348 return descriptors_.recAt(current_ix_)->pc_offset(); | 3344 intptr_t TokenPos() const { return cur_token_pos_; } |
| 3349 } | 3345 intptr_t TryIndex() const { return cur_try_index_; } |
| 3350 intptr_t DeoptId() const { | |
| 3351 NoSafepointScope no_safepoint; | |
| 3352 return descriptors_.recAt(current_ix_)->deopt_id(); | |
| 3353 } | |
| 3354 intptr_t TokenPos() const { | |
| 3355 NoSafepointScope no_safepoint; | |
| 3356 return descriptors_.recAt(current_ix_)->token_pos(); | |
| 3357 } | |
| 3358 intptr_t TryIndex() const { | |
| 3359 NoSafepointScope no_safepoint; | |
| 3360 return descriptors_.recAt(current_ix_)->try_index(); | |
| 3361 } | |
| 3362 RawPcDescriptors::Kind Kind() const { | 3346 RawPcDescriptors::Kind Kind() const { |
| 3363 NoSafepointScope no_safepoint; | 3347 return static_cast<RawPcDescriptors::Kind>(cur_kind_); |
| 3364 return descriptors_.recAt(current_ix_)->kind(); | |
| 3365 } | 3348 } |
| 3366 | 3349 |
| 3367 private: | 3350 private: |
| 3368 friend class PcDescriptors; | 3351 friend class PcDescriptors; |
| 3369 | 3352 |
| 3370 bool HasNext() const { return next_ix_ < descriptors_.Length(); } | |
| 3371 | |
| 3372 // For nested iterations, starting at element after. | 3353 // For nested iterations, starting at element after. |
| 3373 explicit Iterator(const Iterator& iter) | 3354 explicit Iterator(const Iterator& iter) |
| 3374 : ValueObject(), | 3355 : ValueObject(), |
| 3375 descriptors_(iter.descriptors_), | 3356 descriptors_(iter.descriptors_), |
| 3376 kind_mask_(iter.kind_mask_), | 3357 kind_mask_(iter.kind_mask_), |
| 3377 next_ix_(iter.next_ix_), | 3358 byte_index_(iter.byte_index_), |
| 3378 current_ix_(iter.current_ix_) {} | 3359 cur_pc_offset_(iter.cur_pc_offset_), |
| 3379 | 3360 cur_kind_(iter.cur_kind_), |
| 3380 // Moves to record that matches kind_mask_. | 3361 cur_deopt_id_(iter.cur_deopt_id_), |
| 3381 void MoveToMatching() { | 3362 cur_token_pos_(iter.cur_token_pos_), |
| 3382 NoSafepointScope no_safepoint; | 3363 cur_try_index_(iter.cur_try_index_) {} |
| 3383 while (next_ix_ < descriptors_.Length()) { | |
| 3384 const RawPcDescriptors::PcDescriptorRec& rec = | |
| 3385 *descriptors_.recAt(next_ix_); | |
| 3386 if ((rec.kind() & kind_mask_) != 0) { | |
| 3387 return; // Current is valid. | |
| 3388 } else { | |
| 3389 ++next_ix_; | |
| 3390 } | |
| 3391 } | |
| 3392 } | |
| 3393 | 3364 |
| 3394 const PcDescriptors& descriptors_; | 3365 const PcDescriptors& descriptors_; |
| 3395 const intptr_t kind_mask_; | 3366 const intptr_t kind_mask_; |
| 3396 intptr_t next_ix_; | 3367 intptr_t byte_index_; |
| 3397 intptr_t current_ix_; | 3368 |
| 3369 intptr_t cur_pc_offset_; |
| 3370 intptr_t cur_kind_; |
| 3371 intptr_t cur_deopt_id_; |
| 3372 intptr_t cur_token_pos_; |
| 3373 intptr_t cur_try_index_; |
| 3398 }; | 3374 }; |
| 3399 | 3375 |
| 3400 private: | 3376 private: |
| 3401 static const char* KindAsStr(RawPcDescriptors::Kind kind); | 3377 static const char* KindAsStr(RawPcDescriptors::Kind kind); |
| 3402 | 3378 |
| 3403 intptr_t Length() const; | 3379 intptr_t Length() const; |
| 3404 void SetLength(intptr_t value) const; | 3380 void SetLength(intptr_t value) const; |
| 3405 | 3381 void CopyData(GrowableArray<uint8_t>* data); |
| 3406 void SetRecordSizeInBytes(intptr_t value) const; | |
| 3407 intptr_t RecordSizeInBytes() const; | |
| 3408 | |
| 3409 RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const { | |
| 3410 ASSERT((0 <= ix) && (ix < Length())); | |
| 3411 uint8_t* d = UnsafeMutableNonPointer(raw_ptr()->data()) + | |
| 3412 (ix * RecordSizeInBytes()); | |
| 3413 return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d); | |
| 3414 } | |
| 3415 | 3382 |
| 3416 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); | 3383 FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object); |
| 3417 friend class Class; | 3384 friend class Class; |
| 3418 friend class Object; | 3385 friend class Object; |
| 3419 }; | 3386 }; |
| 3420 | 3387 |
| 3421 | 3388 |
| 3422 class Stackmap : public Object { | 3389 class Stackmap : public Object { |
| 3423 public: | 3390 public: |
| 3424 static const intptr_t kNoMaximum = -1; | 3391 static const intptr_t kNoMaximum = -1; |
| (...skipping 4346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7771 | 7738 |
| 7772 | 7739 |
| 7773 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7740 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
| 7774 intptr_t index) { | 7741 intptr_t index) { |
| 7775 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7742 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
| 7776 } | 7743 } |
| 7777 | 7744 |
| 7778 } // namespace dart | 7745 } // namespace dart |
| 7779 | 7746 |
| 7780 #endif // VM_OBJECT_H_ | 7747 #endif // VM_OBJECT_H_ |
| OLD | NEW |