Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 0fda4e48c5fdea78e20feddb11eb607bde8ba93b..f17b7e9eea3f49dc74e728ca8ce694e45099e4b6 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -142,7 +142,6 @@ RawClass* Object::var_descriptors_class_ = |
| reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::exception_handlers_class_ = |
| reinterpret_cast<RawClass*>(RAW_NULL); |
| -RawClass* Object::deopt_info_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| @@ -559,9 +558,6 @@ void Object::InitOnce(Isolate* isolate) { |
| cls = Class::New<ExceptionHandlers>(); |
| exception_handlers_class_ = cls.raw(); |
| - cls = Class::New<DeoptInfo>(); |
| - deopt_info_class_ = cls.raw(); |
| - |
| cls = Class::New<Context>(); |
| context_class_ = cls.raw(); |
| @@ -816,7 +812,6 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { |
| SET_CLASS_NAME(stackmap, Stackmap); |
| SET_CLASS_NAME(var_descriptors, LocalVarDescriptors); |
| SET_CLASS_NAME(exception_handlers, ExceptionHandlers); |
| - SET_CLASS_NAME(deopt_info, DeoptInfo); |
| SET_CLASS_NAME(context, Context); |
| SET_CLASS_NAME(context_scope, ContextScope); |
| SET_CLASS_NAME(icdata, ICData); |
| @@ -3209,8 +3204,6 @@ RawString* Class::GenerateUserVisibleName() const { |
| return Symbols::LocalVarDescriptors().raw(); |
| case kExceptionHandlersCid: |
| return Symbols::ExceptionHandlers().raw(); |
| - case kDeoptInfoCid: |
| - return Symbols::DeoptInfo().raw(); |
| case kContextCid: |
| return Symbols::Context().raw(); |
| case kContextScopeCid: |
| @@ -11140,113 +11133,107 @@ void ExceptionHandlers::PrintJSONImpl(JSONStream* stream, |
| } |
| -intptr_t DeoptInfo::Length() const { |
| - return Smi::Value(raw_ptr()->length_); |
| -} |
| - |
| - |
| -intptr_t DeoptInfo::FromIndex(intptr_t index) const { |
| +intptr_t DeoptInfo::FrameSize(const TypedData& packed) { |
| NoSafepointScope no_safepoint; |
| - return *(EntryAddr(index, kFromIndex)); |
| + typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader; |
| + ReadStream read_stream(reinterpret_cast<uint8_t*>(packed.DataAddr(0)), |
| + packed.LengthInBytes()); |
| + return Reader::Read(&read_stream); |
| } |
| -intptr_t DeoptInfo::Instruction(intptr_t index) const { |
| - NoSafepointScope no_safepoint; |
| - return *(EntryAddr(index, kInstruction)); |
| -} |
| - |
| - |
| -intptr_t DeoptInfo::FrameSize() const { |
| - return TranslationLength() - NumMaterializations(); |
| +intptr_t DeoptInfo::NumMaterializations( |
| + const GrowableArray<DeoptInstr*>& unpacked) { |
| + intptr_t num = 0; |
| + while (unpacked[num]->kind() == DeoptInstr::kMaterializeObject) { |
| + num++; |
| + } |
| + return num; |
| } |
| -intptr_t DeoptInfo::TranslationLength() const { |
| - intptr_t length = Length(); |
| - if (Instruction(length - 1) != DeoptInstr::kSuffix) return length; |
| +void DeoptInfo::UnpackInto(const Array& table, |
| + const TypedData& packed, |
| + GrowableArray<DeoptInstr*>* unpacked, |
| + intptr_t length) { |
| + NoSafepointScope no_safepoint; |
| + typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader; |
| + ReadStream read_stream(reinterpret_cast<uint8_t*>(packed.DataAddr(0)), |
| + packed.LengthInBytes()); |
| + const intptr_t frame_size = Reader::Read(&read_stream); // Skip frame size. |
| + USE(frame_size); |
| - // 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; |
| -} |
| + const intptr_t suffix_length = Reader::Read(&read_stream); |
| + if (suffix_length != 0) { |
| + ASSERT(suffix_length > 1); |
| + const intptr_t info_number = Reader::Read(&read_stream); |
| + TypedData& suffix = TypedData::Handle(); |
| + Smi& offset = Smi::Handle(); |
| + Smi& reason_and_flags = Smi::Handle(); |
| + DeoptTable::GetEntry( |
| + table, info_number, &offset, &suffix, &reason_and_flags); |
| + UnpackInto(table, suffix, unpacked, suffix_length); |
| + } |
| -intptr_t DeoptInfo::NumMaterializations() const { |
| - intptr_t pos = 0; |
| - while (Instruction(pos) == DeoptInstr::kMaterializeObject) { |
| - pos++; |
| + while ((read_stream.PendingBytes() > 0) && |
| + (unpacked->length() < length)) { |
| + const intptr_t instruction = Reader::Read(&read_stream); |
| + const intptr_t from_index = Reader::Read(&read_stream); |
| + unpacked->Add(DeoptInstr::Create(instruction, from_index)); |
| } |
| - return pos; |
| } |
| -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_and_flags = 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_and_flags); |
| - length = info.TranslationLength(); |
| - index = length - suffix_length; |
| - } else { |
| - instructions->Add(DeoptInstr::Create(instruction, from_index)); |
| - ++index; |
| - } |
| +void DeoptInfo::Unpack(const Array& table, |
| + const TypedData& packed, |
| + GrowableArray<DeoptInstr*>* unpacked) { |
| + ASSERT(unpacked->is_empty()); |
| + UnpackInto(table, packed, unpacked, kMaxInt32); |
|
Ivan Posva
2015/04/08 07:12:13
It is not really obvious why kMaxInt32 is being pa
Vyacheslav Egorov (Google)
2015/04/08 13:07:39
Done.
|
| + |
| + const intptr_t length = unpacked->length(); |
|
Florian Schneider
2015/04/08 08:50:04
Add a reverse method to GrowableArray?
Vyacheslav Egorov (Google)
2015/04/08 13:07:39
Done.
|
| + for (intptr_t i = 0; i < length / 2; i++) { |
| + intptr_t j = length - 1 - i; |
| + DeoptInstr* temp = (*unpacked)[i]; |
| + (*unpacked)[i] = (*unpacked)[j]; |
| + (*unpacked)[j] = temp; |
| } |
| } |
| -const char* DeoptInfo::ToCString() const { |
| - if (Length() == 0) { |
| - return "No DeoptInfo"; |
| - } |
| - // Convert to DeoptInstr. |
| - GrowableArray<DeoptInstr*> deopt_instrs(Length()); |
| - for (intptr_t i = 0; i < Length(); i++) { |
| - deopt_instrs.Add(DeoptInstr::Create(Instruction(i), FromIndex(i))); |
| - } |
| +const char* DeoptInfo::ToCString(const Array& deopt_table, |
| + const TypedData& packed) { |
| + GrowableArray<DeoptInstr*> deopt_instrs; |
| + Unpack(deopt_table, packed, &deopt_instrs); |
| + |
| // 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 < deopt_instrs.length(); 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 < deopt_instrs.length(); i++) { |
| index += OS::SNPrint((buffer + index), |
| (len - index), |
| "[%s]", |
| deopt_instrs[i]->ToCString()); |
| } |
| + |
| return buffer; |
| } |
| // Returns a bool so it can be asserted. |
| bool DeoptInfo::VerifyDecompression(const GrowableArray<DeoptInstr*>& original, |
| - const Array& deopt_table) const { |
| - intptr_t length = TranslationLength(); |
| - GrowableArray<DeoptInstr*> unpacked(length); |
| - ToInstructions(deopt_table, &unpacked); |
| + const Array& deopt_table, |
| + const TypedData& packed) { |
| + GrowableArray<DeoptInstr*> unpacked; |
| + Unpack(deopt_table, packed, &unpacked); |
| ASSERT(unpacked.length() == original.length()); |
| for (intptr_t i = 0; i < unpacked.length(); ++i) { |
| ASSERT(unpacked[i]->Equals(*original[i])); |
| @@ -11255,47 +11242,6 @@ bool DeoptInfo::VerifyDecompression(const GrowableArray<DeoptInstr*>& original, |
| } |
| -void DeoptInfo::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| - Object::PrintJSONImpl(stream, ref); |
| -} |
| - |
| - |
| -RawDeoptInfo* DeoptInfo::New(intptr_t num_commands) { |
| - ASSERT(Object::deopt_info_class() != Class::null()); |
| - if ((num_commands < 0) || (num_commands > kMaxElements)) { |
| - FATAL1("Fatal error in DeoptInfo::New(): invalid num_commands %" Pd "\n", |
| - num_commands); |
| - } |
| - DeoptInfo& result = DeoptInfo::Handle(); |
| - { |
| - uword size = DeoptInfo::InstanceSize(num_commands); |
| - RawObject* raw = Object::Allocate(DeoptInfo::kClassId, |
| - size, |
| - Heap::kOld); |
| - NoSafepointScope no_safepoint; |
| - result ^= raw; |
| - result.SetLength(num_commands); |
| - } |
| - return result.raw(); |
| -} |
| - |
| - |
| -void DeoptInfo::SetLength(intptr_t value) const { |
| - // This is only safe because we create a new Smi, which does not cause |
| - // heap allocation. |
| - StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
| -} |
| - |
| - |
| -void DeoptInfo::SetAt(intptr_t index, |
| - intptr_t instr_kind, |
| - intptr_t from_index) const { |
| - NoSafepointScope no_safepoint; |
| - *(EntryAddr(index, kInstruction)) = instr_kind; |
| - *(EntryAddr(index, kFromIndex)) = from_index; |
| -} |
| - |
| - |
| const char* ICData::ToCString() const { |
| const char* kFormat = "ICData target:'%s' num-args: %" Pd |
| " num-checks: %" Pd ""; |
| @@ -12108,7 +12054,7 @@ bool Code::HasBreakpoint() const { |
| } |
| -RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc, |
| +RawTypedData* Code::GetDeoptInfoAtPc(uword pc, |
| ICData::DeoptReasonId* deopt_reason, |
| uint32_t* deopt_flags) const { |
| ASSERT(is_optimized()); |
| @@ -12120,7 +12066,7 @@ RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc, |
| intptr_t length = DeoptTable::GetLength(table); |
| Smi& offset = Smi::Handle(); |
| Smi& reason_and_flags = Smi::Handle(); |
| - DeoptInfo& info = DeoptInfo::Handle(); |
| + TypedData& info = TypedData::Handle(); |
| for (intptr_t i = 0; i < length; ++i) { |
| DeoptTable::GetEntry(table, i, &offset, &info, &reason_and_flags); |
| if (pc == (code_entry + offset.Value())) { |
| @@ -12131,7 +12077,7 @@ RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc, |
| } |
| } |
| *deopt_reason = ICData::kDeoptUnknown; |
| - return DeoptInfo::null(); |
| + return TypedData::null(); |
| } |