| Index: runtime/vm/object.h
|
| diff --git a/runtime/vm/object.h b/runtime/vm/object.h
|
| index 0b7e131bb774a8e5c05df3d4086e9889fa0e4ae1..cd464c8fcb2b11c33eb2cecad50b0a7692251505 100644
|
| --- a/runtime/vm/object.h
|
| +++ b/runtime/vm/object.h
|
| @@ -3274,20 +3274,43 @@ class LocalVarDescriptors : public Object {
|
|
|
| class PcDescriptors : public Object {
|
| public:
|
| - static const intptr_t kBytesPerElement = 1;
|
| - static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
|
| + void AddDescriptor(intptr_t index,
|
| + uword pc_offset,
|
| + RawPcDescriptors::Kind kind,
|
| + int64_t deopt_id,
|
| + int64_t token_pos, // Or deopt reason.
|
| + intptr_t try_index) const { // Or deopt index.
|
| + NoSafepointScope no_safepoint;
|
| + RawPcDescriptors::PcDescriptorRec* rec = recAt(index);
|
| + rec->set_pc_offset(pc_offset);
|
| + rec->set_kind(kind);
|
| + ASSERT(Utils::IsInt(32, deopt_id));
|
| + rec->set_deopt_id(static_cast<int32_t>(deopt_id));
|
| + ASSERT(Utils::IsInt(32, token_pos));
|
| + rec->set_token_pos(static_cast<int32_t>(token_pos),
|
| + RecordSizeInBytes() == RawPcDescriptors::kCompressedRecSize);
|
| + ASSERT(Utils::IsInt(16, try_index));
|
| + rec->set_try_index(try_index);
|
| + ASSERT(rec->try_index() == try_index);
|
| + ASSERT(rec->token_pos() == token_pos);
|
| + }
|
| +
|
| + static const intptr_t kMaxBytesPerElement =
|
| + sizeof(RawPcDescriptors::PcDescriptorRec);
|
| + static const intptr_t kMaxElements = kMaxInt32 / kMaxBytesPerElement;
|
|
|
| static intptr_t InstanceSize() {
|
| ASSERT(sizeof(RawPcDescriptors) ==
|
| OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data));
|
| return 0;
|
| }
|
| - static intptr_t InstanceSize(intptr_t len) {
|
| + static intptr_t InstanceSize(intptr_t len, intptr_t record_size_in_bytes) {
|
| ASSERT(0 <= len && len <= kMaxElements);
|
| - return RoundedAllocationSize(sizeof(RawPcDescriptors) + len);
|
| + return RoundedAllocationSize(
|
| + sizeof(RawPcDescriptors) + (len * record_size_in_bytes));
|
| }
|
|
|
| - static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data);
|
| + static RawPcDescriptors* New(intptr_t num_descriptors, bool has_try_index);
|
|
|
| // Verify (assert) assumptions about pc descriptors in debug mode.
|
| void Verify(const Function& function) const;
|
| @@ -3296,12 +3319,6 @@ class PcDescriptors : public Object {
|
|
|
| void PrintToJSONObject(JSONObject* jsobj, bool ref) const;
|
|
|
| - // Encode integer in SLEB128 format.
|
| - static void EncodeInteger(GrowableArray<uint8_t>* data, intptr_t value);
|
| -
|
| - // Decode SLEB128 encoded integer. Update byte_index to the next integer.
|
| - intptr_t DecodeInteger(intptr_t* byte_index) const;
|
| -
|
| // We would have a VisitPointers function here to traverse the
|
| // pc descriptors table to visit objects if any in the table.
|
| // Note: never return a reference to a RawPcDescriptors::PcDescriptorRec
|
| @@ -3311,62 +3328,73 @@ class PcDescriptors : public Object {
|
| Iterator(const PcDescriptors& descriptors, intptr_t kind_mask)
|
| : descriptors_(descriptors),
|
| kind_mask_(kind_mask),
|
| - byte_index_(0),
|
| - cur_pc_offset_(0),
|
| - cur_kind_(0),
|
| - cur_deopt_id_(0),
|
| - cur_token_pos_(0),
|
| - cur_try_index_(0) {
|
| + next_ix_(0),
|
| + current_ix_(-1) {
|
| + MoveToMatching();
|
| }
|
|
|
| bool MoveNext() {
|
| - // Moves to record that matches kind_mask_.
|
| - while (byte_index_ < descriptors_.Length()) {
|
| - cur_kind_ = descriptors_.DecodeInteger(&byte_index_);
|
| - cur_try_index_ = descriptors_.DecodeInteger(&byte_index_);
|
| - cur_pc_offset_ += descriptors_.DecodeInteger(&byte_index_);
|
| - cur_deopt_id_ += descriptors_.DecodeInteger(&byte_index_);
|
| - cur_token_pos_ += descriptors_.DecodeInteger(&byte_index_);
|
| -
|
| - if ((cur_kind_ & kind_mask_) != 0) {
|
| - return true; // Current is valid.
|
| - }
|
| + if (HasNext()) {
|
| + current_ix_ = next_ix_++;
|
| + MoveToMatching();
|
| + return true;
|
| + } else {
|
| + return false;
|
| }
|
| - return false;
|
| }
|
|
|
| - uword PcOffset() const { return cur_pc_offset_; }
|
| - intptr_t DeoptId() const { return cur_deopt_id_; }
|
| - intptr_t TokenPos() const { return cur_token_pos_; }
|
| - intptr_t TryIndex() const { return cur_try_index_; }
|
| + uword PcOffset() const {
|
| + NoSafepointScope no_safepoint;
|
| + return descriptors_.recAt(current_ix_)->pc_offset();
|
| + }
|
| + intptr_t DeoptId() const {
|
| + NoSafepointScope no_safepoint;
|
| + return descriptors_.recAt(current_ix_)->deopt_id();
|
| + }
|
| + intptr_t TokenPos() const {
|
| + NoSafepointScope no_safepoint;
|
| + return descriptors_.recAt(current_ix_)->token_pos();
|
| + }
|
| + intptr_t TryIndex() const {
|
| + NoSafepointScope no_safepoint;
|
| + return descriptors_.recAt(current_ix_)->try_index();
|
| + }
|
| RawPcDescriptors::Kind Kind() const {
|
| - return static_cast<RawPcDescriptors::Kind>(cur_kind_);
|
| + NoSafepointScope no_safepoint;
|
| + return descriptors_.recAt(current_ix_)->kind();
|
| }
|
|
|
| private:
|
| friend class PcDescriptors;
|
|
|
| + bool HasNext() const { return next_ix_ < descriptors_.Length(); }
|
| +
|
| // For nested iterations, starting at element after.
|
| explicit Iterator(const Iterator& iter)
|
| : ValueObject(),
|
| descriptors_(iter.descriptors_),
|
| kind_mask_(iter.kind_mask_),
|
| - byte_index_(iter.byte_index_),
|
| - cur_pc_offset_(iter.cur_pc_offset_),
|
| - cur_kind_(iter.cur_kind_),
|
| - cur_deopt_id_(iter.cur_deopt_id_),
|
| - cur_token_pos_(iter.cur_token_pos_),
|
| - cur_try_index_(iter.cur_try_index_) {}
|
| + next_ix_(iter.next_ix_),
|
| + current_ix_(iter.current_ix_) {}
|
| +
|
| + // Moves to record that matches kind_mask_.
|
| + void MoveToMatching() {
|
| + NoSafepointScope no_safepoint;
|
| + while (next_ix_ < descriptors_.Length()) {
|
| + const RawPcDescriptors::PcDescriptorRec& rec =
|
| + *descriptors_.recAt(next_ix_);
|
| + if ((rec.kind() & kind_mask_) != 0) {
|
| + return; // Current is valid.
|
| + } else {
|
| + ++next_ix_;
|
| + }
|
| + }
|
| + }
|
|
|
| const PcDescriptors& descriptors_;
|
| const intptr_t kind_mask_;
|
| - intptr_t byte_index_;
|
| -
|
| - intptr_t cur_pc_offset_;
|
| - intptr_t cur_kind_;
|
| - intptr_t cur_deopt_id_;
|
| - intptr_t cur_token_pos_;
|
| - intptr_t cur_try_index_;
|
| + intptr_t next_ix_;
|
| + intptr_t current_ix_;
|
| };
|
|
|
| private:
|
| @@ -3374,7 +3402,16 @@ class PcDescriptors : public Object {
|
|
|
| intptr_t Length() const;
|
| void SetLength(intptr_t value) const;
|
| - void CopyData(GrowableArray<uint8_t>* data);
|
| +
|
| + void SetRecordSizeInBytes(intptr_t value) const;
|
| + intptr_t RecordSizeInBytes() const;
|
| +
|
| + RawPcDescriptors::PcDescriptorRec* recAt(intptr_t ix) const {
|
| + ASSERT((0 <= ix) && (ix < Length()));
|
| + uint8_t* d = UnsafeMutableNonPointer(raw_ptr()->data()) +
|
| + (ix * RecordSizeInBytes());
|
| + return reinterpret_cast<RawPcDescriptors::PcDescriptorRec*>(d);
|
| + }
|
|
|
| FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object);
|
| friend class Class;
|
|
|