Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 14e54ef0f8531a7356c80c7b8b86034117d7fdf6..df6fde0d7ba841ad7fb6223f3caf2ec26c7bb876 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -141,6 +141,8 @@ RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
+RawClass* Object::code_source_map_class_ = |
+ reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::var_descriptors_class_ = |
reinterpret_cast<RawClass*>(RAW_NULL); |
@@ -613,6 +615,9 @@ void Object::InitOnce(Isolate* isolate) { |
cls = Class::New<PcDescriptors>(); |
pc_descriptors_class_ = cls.raw(); |
+ cls = Class::New<CodeSourceMap>(); |
+ code_source_map_class_ = cls.raw(); |
+ |
cls = Class::New<Stackmap>(); |
stackmap_class_ = cls.raw(); |
@@ -945,6 +950,7 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { |
SET_CLASS_NAME(code, Code); |
SET_CLASS_NAME(instructions, Instructions); |
SET_CLASS_NAME(object_pool, ObjectPool); |
+ SET_CLASS_NAME(code_source_map, CodeSourceMap); |
SET_CLASS_NAME(pc_descriptors, PcDescriptors); |
SET_CLASS_NAME(stackmap, Stackmap); |
SET_CLASS_NAME(var_descriptors, LocalVarDescriptors); |
@@ -3250,6 +3256,8 @@ RawString* Class::GenerateUserVisibleName() const { |
return Symbols::Instructions().raw(); |
case kObjectPoolCid: |
return Symbols::ObjectPool().raw(); |
+ case kCodeSourceMapCid: |
+ return Symbols::CodeSourceMap().raw(); |
case kPcDescriptorsCid: |
return Symbols::PcDescriptors().raw(); |
case kStackmapCid: |
@@ -11158,9 +11166,9 @@ void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const { |
} |
-// Encode integer in SLEB128 format. |
-void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, |
- intptr_t value) { |
+// Encode integer |value| in SLEB128 format and store into |data|. |
+static void EncodeSLEB128(GrowableArray<uint8_t>* data, |
+ intptr_t value) { |
bool is_last_part = false; |
while (!is_last_part) { |
uint8_t part = value & 0x7f; |
@@ -11176,11 +11184,11 @@ void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, |
} |
-// Decode SLEB128 encoded integer. Update byte_index to the next integer. |
-intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |
- NoSafepointScope no_safepoint; |
- const uint8_t* data = raw_ptr()->data(); |
- ASSERT(*byte_index < Length()); |
+// Decode integer in SLEB128 format from |data| and update |byte_index|. |
+static intptr_t DecodeSLEB128(const uint8_t* data, |
+ const intptr_t data_length, |
+ intptr_t* byte_index) { |
+ ASSERT(*byte_index < data_length); |
uword shift = 0; |
intptr_t value = 0; |
uint8_t part = 0; |
@@ -11197,6 +11205,21 @@ intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |
} |
+// Encode integer in SLEB128 format. |
+void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, |
+ intptr_t value) { |
+ return EncodeSLEB128(data, value); |
+} |
+ |
+ |
+// Decode SLEB128 encoded integer. Update byte_index to the next integer. |
+intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |
+ NoSafepointScope no_safepoint; |
+ const uint8_t* data = raw_ptr()->data(); |
+ return DecodeSLEB128(data, Length(), byte_index); |
+} |
+ |
+ |
RawObjectPool* ObjectPool::New(intptr_t len) { |
ASSERT(Object::object_pool_class() != Class::null()); |
if (len < 0 || len > kMaxElements) { |
@@ -11495,6 +11518,114 @@ void PcDescriptors::Verify(const Function& function) const { |
} |
+intptr_t CodeSourceMap::Length() const { |
+ return raw_ptr()->length_; |
+} |
+ |
+ |
+void CodeSourceMap::SetLength(intptr_t value) const { |
+ StoreNonPointer(&raw_ptr()->length_, value); |
+} |
+ |
+ |
+void CodeSourceMap::CopyData(GrowableArray<uint8_t>* delta_encoded_data) { |
+ NoSafepointScope no_safepoint; |
+ uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]); |
+ for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) { |
+ data[i] = (*delta_encoded_data)[i]; |
+ } |
+} |
+ |
+ |
+RawCodeSourceMap* CodeSourceMap::New(GrowableArray<uint8_t>* data) { |
+ ASSERT(Object::code_source_map_class() != Class::null()); |
+ Thread* thread = Thread::Current(); |
+ CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); |
+ { |
+ uword size = CodeSourceMap::InstanceSize(data->length()); |
+ RawObject* raw = Object::Allocate(CodeSourceMap::kClassId, |
+ size, |
+ Heap::kOld); |
+ NoSafepointScope no_safepoint; |
+ result ^= raw; |
+ result.SetLength(data->length()); |
+ result.CopyData(data); |
+ } |
+ return result.raw(); |
+} |
+ |
+ |
+RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { |
+ ASSERT(Object::code_source_map_class() != Class::null()); |
+ Thread* thread = Thread::Current(); |
+ CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); |
+ { |
+ uword size = CodeSourceMap::InstanceSize(length); |
+ RawObject* raw = Object::Allocate(CodeSourceMap::kClassId, |
+ size, |
+ Heap::kOld); |
+ NoSafepointScope no_safepoint; |
+ result ^= raw; |
+ result.SetLength(length); |
+ } |
+ return result.raw(); |
+} |
+ |
+ |
+void CodeSourceMap::PrintJSONImpl(JSONStream* stream, bool ref) const { |
+ Object::PrintJSONImpl(stream, ref); |
+} |
+ |
+ |
+const char* CodeSourceMap::ToCString() const { |
+ // "*" in a printf format specifier tells it to read the field width from |
+ // the printf argument list. |
+#define FORMAT "%#-*" Px "\t%" Pd "\n" |
+ if (Length() == 0) { |
+ return "empty CodeSourceMap\n"; |
+ } |
+ // 4 bits per hex digit. |
+ const int addr_width = kBitsPerWord / 4; |
+ // First compute the buffer size required. |
+ intptr_t len = 1; // Trailing '\0'. |
+ { |
+ Iterator iter(*this); |
+ while (iter.MoveNext()) { |
+ len += OS::SNPrint(NULL, 0, FORMAT, addr_width, |
+ iter.PcOffset(), |
+ iter.TokenPos()); |
+ } |
+ } |
+ // Allocate the buffer. |
+ char* buffer = Thread::Current()->zone()->Alloc<char>(len); |
+ // Layout the fields in the buffer. |
+ intptr_t index = 0; |
+ Iterator iter(*this); |
+ while (iter.MoveNext()) { |
+ index += OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width, |
+ iter.PcOffset(), |
+ iter.TokenPos()); |
+ } |
+ return buffer; |
+#undef FORMAT |
+} |
+ |
+ |
+// Encode integer in SLEB128 format. |
+void CodeSourceMap::EncodeInteger(GrowableArray<uint8_t>* data, |
+ intptr_t value) { |
+ return EncodeSLEB128(data, value); |
+} |
+ |
+ |
+// Decode SLEB128 encoded integer. Update byte_index to the next integer. |
+intptr_t CodeSourceMap::DecodeInteger(intptr_t* byte_index) const { |
+ NoSafepointScope no_safepoint; |
+ const uint8_t* data = raw_ptr()->data(); |
+ return DecodeSLEB128(data, Length(), byte_index); |
+} |
+ |
+ |
bool Stackmap::GetBit(intptr_t bit_index) const { |
ASSERT(InRange(bit_index)); |
int byte_index = bit_index >> kBitsPerByteLog2; |