Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Unified Diff: runtime/vm/object.cc

Issue 1054393003: Compress deopt instructions in memory using variable length encoding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: landing Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 0fda4e48c5fdea78e20feddb11eb607bde8ba93b..50ce7d7d9f89d97e3cc748807361d00e3a738efd 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,104 @@ 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::NumMaterializations(
+ const GrowableArray<DeoptInstr*>& unpacked) {
+ intptr_t num = 0;
+ while (unpacked[num]->kind() == DeoptInstr::kMaterializeObject) {
+ num++;
+ }
+ return num;
}
-intptr_t DeoptInfo::FrameSize() const {
- return TranslationLength() - NumMaterializations();
-}
+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);
+ 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);
-intptr_t DeoptInfo::TranslationLength() const {
- intptr_t length = Length();
- if (Instruction(length - 1) != DeoptInstr::kSuffix) return length;
+ 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);
+ }
- // 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;
+ 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));
+ }
}
-intptr_t DeoptInfo::NumMaterializations() const {
- intptr_t pos = 0;
- while (Instruction(pos) == DeoptInstr::kMaterializeObject) {
- pos++;
- }
- return pos;
-}
+void DeoptInfo::Unpack(const Array& table,
+ const TypedData& packed,
+ GrowableArray<DeoptInstr*>* unpacked) {
+ ASSERT(unpacked->is_empty());
+ // Pass kMaxInt32 as the length to unpack all instructions from the
+ // packed stream.
+ UnpackInto(table, packed, unpacked, kMaxInt32);
-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;
- }
- }
+ unpacked->Reverse();
}
-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 +11239,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 +12051,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 +12063,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 +12074,7 @@ RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc,
}
}
*deopt_reason = ICData::kDeoptUnknown;
- return DeoptInfo::null();
+ return TypedData::null();
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698