| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index 9787d2bd8b68055bd450b97bb6ebfc8106734a99..e2fbcff1c9bac6fb2db2ba6d084802d133c0176e 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -6780,7 +6780,7 @@ const char* ExceptionHandlers::ToCString() const {
|
| }
|
|
|
|
|
| -intptr_t DeoptInfo::Length() const {
|
| +intptr_t DeoptInfo::GetLength() const {
|
| return Smi::Value(raw_ptr()->length_);
|
| }
|
|
|
| @@ -6795,25 +6795,66 @@ intptr_t DeoptInfo::Instruction(intptr_t index) const {
|
| }
|
|
|
|
|
| +intptr_t DeoptInfo::TranslationLength() const {
|
| + intptr_t length = GetLength();
|
| + if (Instruction(length - 1) != DeoptInstr::kSuffix) return length;
|
| +
|
| + // If the last command is a suffix, add in the length of the suffix and
|
| + // do not count the suffix command as a translation command.
|
| + intptr_t ignored = 0;
|
| + intptr_t suffix_length =
|
| + DeoptInstr::DecodeSuffix(FromIndex(length - 1), &ignored);
|
| + return length + suffix_length - 1;
|
| +}
|
| +
|
| +
|
| +void DeoptInfo::ToInstructions(const Array& table,
|
| + GrowableArray<DeoptInstr*>* instructions) const {
|
| + ASSERT(instructions->is_empty());
|
| + Smi& offset = Smi::Handle();
|
| + DeoptInfo& info = DeoptInfo::Handle(raw());
|
| + Smi& reason = Smi::Handle();
|
| + intptr_t index = 0;
|
| + intptr_t length = TranslationLength();
|
| + while (index < length) {
|
| + intptr_t instruction = info.Instruction(index);
|
| + intptr_t from_index = info.FromIndex(index);
|
| + if (instruction == DeoptInstr::kSuffix) {
|
| + // Suffix instructions cause us to 'jump' to another translation,
|
| + // changing info, length and index.
|
| + intptr_t info_number = 0;
|
| + intptr_t suffix_length =
|
| + DeoptInstr::DecodeSuffix(from_index, &info_number);
|
| + DeoptTable::GetEntry(table, info_number, &offset, &info, &reason);
|
| + length = info.TranslationLength();
|
| + index = length - suffix_length;
|
| + } else {
|
| + instructions->Add(DeoptInstr::Create(instruction, from_index));
|
| + ++index;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| const char* DeoptInfo::ToCString() const {
|
| - if (Length() == 0) {
|
| + if (GetLength() == 0) {
|
| return "No DeoptInfo";
|
| }
|
| // Convert to DeoptInstr.
|
| - GrowableArray<DeoptInstr*> deopt_instrs(Length());
|
| - for (intptr_t i = 0; i < Length(); i++) {
|
| + GrowableArray<DeoptInstr*> deopt_instrs(GetLength());
|
| + for (intptr_t i = 0; i < GetLength(); i++) {
|
| deopt_instrs.Add(DeoptInstr::Create(Instruction(i), FromIndex(i)));
|
| }
|
| // Compute the buffer size required.
|
| intptr_t len = 1; // Trailing '\0'.
|
| - for (intptr_t i = 0; i < Length(); i++) {
|
| + for (intptr_t i = 0; i < GetLength(); i++) {
|
| len += OS::SNPrint(NULL, 0, "[%s]", deopt_instrs[i]->ToCString());
|
| }
|
| // Allocate the buffer.
|
| char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len);
|
| // Layout the fields in the buffer.
|
| intptr_t index = 0;
|
| - for (intptr_t i = 0; i < Length(); i++) {
|
| + for (intptr_t i = 0; i < GetLength(); i++) {
|
| index += OS::SNPrint((buffer + index),
|
| (len - index),
|
| "[%s]",
|
|
|