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

Unified Diff: runtime/vm/object.cc

Issue 2670843006: Encode inlining information in CodeSourceMap and remove inlining interval arrays. (Closed)
Patch Set: . Created 3 years, 10 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/object_service.cc » ('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 b2b922b9888876b4bbc48aaa3217edad5b2bed53..8df9f9333e007d2bbbb11a80e977f1c75be8093a 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -12096,117 +12096,11 @@ void PcDescriptors::Verify(const Function& function) const {
}
-TokenPosition CodeSourceMap::TokenPositionForPCOffset(uword pc_offset) const {
- Iterator iterator(*this);
-
- TokenPosition result = TokenPosition::kNoSource;
-
- while (iterator.MoveNext()) {
- if (iterator.PcOffset() > pc_offset) {
- break;
- }
- result = iterator.TokenPos();
- }
-
- return result;
-}
-
-
-RawFunction* CodeSourceMap::FunctionForPCOffset(const Code& code,
- const Function& function,
- uword pc_offset) const {
- GrowableArray<Function*> inlined_functions;
- code.GetInlinedFunctionsAt(pc_offset, &inlined_functions);
- if (inlined_functions.length() > 0) {
- Function* inlined_function = inlined_functions[0];
- return inlined_function->raw();
- } else {
- return function.raw();
- }
-}
-
-
-RawScript* CodeSourceMap::ScriptForPCOffset(const Code& code,
- const Function& function,
- uword pc_offset) const {
- const Function& func =
- Function::Handle(FunctionForPCOffset(code, function, pc_offset));
- return func.script();
-}
-
-
-void CodeSourceMap::Dump(const CodeSourceMap& code_source_map,
- const Code& code,
- const Function& function) {
- const char* code_name = code.QualifiedName();
- THR_Print("Dumping Code Source Map for %s\n", code_name);
- if (code_source_map.Length() == 0) {
- THR_Print("<empty>\n");
- return;
- }
-
- const int addr_width = kBitsPerWord / 4;
-
- Iterator iterator(code_source_map);
- Function& current_function = Function::Handle();
- Script& current_script = Script::Handle();
- TokenPosition tp;
- while (iterator.MoveNext()) {
- const uword pc_offset = iterator.PcOffset();
- tp = code_source_map.TokenPositionForPCOffset(pc_offset);
- current_function ^=
- code_source_map.FunctionForPCOffset(code, function, pc_offset);
- current_script ^=
- code_source_map.ScriptForPCOffset(code, function, pc_offset);
- if (current_function.IsNull() || current_script.IsNull()) {
- THR_Print("%#-*" Px "\t%s\t%s\n", addr_width, pc_offset, tp.ToCString(),
- code_name);
- continue;
- }
- const String& uri = String::Handle(current_script.url());
- ASSERT(!uri.IsNull());
- THR_Print("%#-*" Px "\t%s\t%s\t%s\n", addr_width, pc_offset, tp.ToCString(),
- current_function.ToQualifiedCString(), uri.ToCString());
- }
-}
-
-
-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();
@@ -12224,49 +12118,7 @@ RawCodeSourceMap* CodeSourceMap::New(intptr_t length) {
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%s\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().ToCString());
- }
- }
- // 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().ToCString());
- }
- 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);
+ return "CodeSourceMap";
}
@@ -14047,15 +13899,6 @@ bool Code::HasBreakpoint() const {
}
-TokenPosition Code::GetTokenPositionAt(intptr_t offset) const {
- const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
- if (map.IsNull()) {
- return TokenPosition::kNoSource;
- }
- return map.TokenPositionForPCOffset(offset);
-}
-
-
RawTypedData* Code::GetDeoptInfoAtPc(uword pc,
ICData::DeoptReasonId* deopt_reason,
uint32_t* deopt_flags) const {
@@ -14243,126 +14086,21 @@ intptr_t Code::GetPrologueOffset() const {
}
-RawArray* Code::GetInlinedIntervals() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return Array::null();
-#else
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- if (metadata.IsNull()) {
- return metadata.raw();
- }
- return reinterpret_cast<RawArray*>(
- metadata.At(RawCode::kInlinedIntervalsIndex));
-#endif
-}
-
-
-void Code::SetInlinedIntervals(const Array& value) const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- if (raw_ptr()->inlined_metadata_ == Array::null()) {
- StorePointer(&raw_ptr()->inlined_metadata_,
- Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
- }
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- ASSERT(!metadata.IsNull());
- ASSERT(metadata.IsOld());
- ASSERT(value.IsOld());
- metadata.SetAt(RawCode::kInlinedIntervalsIndex, value);
-#endif
-}
-
-
-RawArray* Code::GetInlinedIdToFunction() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return Array::null();
-#else
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- if (metadata.IsNull()) {
- return metadata.raw();
- }
- return reinterpret_cast<RawArray*>(
- metadata.At(RawCode::kInlinedIdToFunctionIndex));
-#endif
-}
-
-
-void Code::SetInlinedIdToFunction(const Array& value) const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- if (raw_ptr()->inlined_metadata_ == Array::null()) {
- StorePointer(&raw_ptr()->inlined_metadata_,
- Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
- }
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- ASSERT(!metadata.IsNull());
- ASSERT(metadata.IsOld());
- ASSERT(value.IsOld());
- metadata.SetAt(RawCode::kInlinedIdToFunctionIndex, value);
-#endif
-}
-
-
-RawArray* Code::GetInlinedIdToTokenPos() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return Array::null();
-#else
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- if (metadata.IsNull()) {
- return metadata.raw();
- }
- return reinterpret_cast<RawArray*>(
- metadata.At(RawCode::kInlinedIdToTokenPosIndex));
-#endif
-}
-
-
-void Code::SetInlinedIdToTokenPos(const Array& value) const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- if (raw_ptr()->inlined_metadata_ == Array::null()) {
- StorePointer(&raw_ptr()->inlined_metadata_,
- Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
- }
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- ASSERT(!metadata.IsNull());
- ASSERT(metadata.IsOld());
- ASSERT(value.IsOld());
- metadata.SetAt(RawCode::kInlinedIdToTokenPosIndex, value);
-#endif
-}
-
-
-RawArray* Code::GetInlinedCallerIdMap() const {
+RawArray* Code::inlined_id_to_function() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return Array::null();
#else
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- if (metadata.IsNull()) {
- return metadata.raw();
- }
- return reinterpret_cast<RawArray*>(
- metadata.At(RawCode::kInlinedCallerIdMapIndex));
+ return raw_ptr()->inlined_id_to_function_;
#endif
}
-void Code::SetInlinedCallerIdMap(const Array& value) const {
+void Code::set_inlined_id_to_function(const Array& value) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
- if (raw_ptr()->inlined_metadata_ == Array::null()) {
- StorePointer(&raw_ptr()->inlined_metadata_,
- Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
- }
- const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
- ASSERT(!metadata.IsNull());
- ASSERT(metadata.IsOld());
ASSERT(value.IsOld());
- metadata.SetAt(RawCode::kInlinedCallerIdMapIndex, value);
+ StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
#endif
}
@@ -14722,126 +14460,59 @@ RawStackMap* Code::GetStackMap(uint32_t pc_offset,
}
-intptr_t Code::GetCallerId(intptr_t inlined_id) const {
- if (inlined_id < 0) {
- return -1;
- }
- const Array& map = Array::Handle(GetInlinedCallerIdMap());
- if (map.IsNull() || (map.Length() == 0)) {
- return -1;
+void Code::GetInlinedFunctionsAt(
+ intptr_t pc_offset,
+ GrowableArray<const Function*>* functions,
+ GrowableArray<TokenPosition>* token_positions) const {
+ const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
+ if (map.IsNull()) {
+ // Stub code.
+ return;
}
- Smi& smi = Smi::Handle();
- smi ^= map.At(inlined_id);
- return smi.Value();
+ const Array& id_map = Array::Handle(inlined_id_to_function());
+ const Function& root = Function::Handle(function());
+ CodeSourceMapReader reader(map, id_map, root);
+ reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions);
}
-void Code::GetInlinedFunctionsAt(
- intptr_t offset,
- GrowableArray<Function*>* fs,
- GrowableArray<TokenPosition>* token_positions) const {
- fs->Clear();
- if (token_positions != NULL) {
- token_positions->Clear();
+#ifndef PRODUCT
+void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const {
+ if (!is_optimized()) {
+ return; // No inlining.
}
- const Array& intervals = Array::Handle(GetInlinedIntervals());
- if (intervals.IsNull() || (intervals.Length() == 0)) {
- // E.g., for code stubs.
+ const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
+ const Array& id_map = Array::Handle(inlined_id_to_function());
+ const Function& root = Function::Handle(function());
+ CodeSourceMapReader reader(map, id_map, root);
+ reader.PrintJSONInlineIntervals(jsobj);
+}
+#endif
+
+
+void Code::DumpInlineIntervals() const {
+ const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
+ if (map.IsNull()) {
+ // Stub code.
return;
}
- // First find the right interval. TODO(srdjan): use binary search since
- // intervals are sorted.
- Smi& start = Smi::Handle();
- Smi& end = Smi::Handle();
- intptr_t found_interval_ix = intervals.Length() - Code::kInlIntNumEntries;
- for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries;
- i += Code::kInlIntNumEntries) {
- start ^= intervals.At(i + Code::kInlIntStart);
- if (!start.IsNull()) {
- end ^= intervals.At(i + Code::kInlIntNumEntries + Code::kInlIntStart);
- if ((start.Value() <= offset) && (offset < end.Value())) {
- found_interval_ix = i;
- break;
- }
- }
- }
+ const Array& id_map = Array::Handle(inlined_id_to_function());
+ const Function& root = Function::Handle(function());
+ CodeSourceMapReader reader(map, id_map, root);
+ reader.DumpInlineIntervals(PayloadStart());
+}
- // Find all functions.
- const Array& id_map = Array::Handle(GetInlinedIdToFunction());
- const Array& token_pos_map = Array::Handle(GetInlinedIdToTokenPos());
- Smi& temp_smi = Smi::Handle();
- temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntInliningId);
- intptr_t inlining_id = temp_smi.Value();
- ASSERT(inlining_id >= 0);
- intptr_t caller_id = GetCallerId(inlining_id);
- while (inlining_id >= 0) {
- Function& function = Function::ZoneHandle();
- function ^= id_map.At(inlining_id);
- fs->Add(&function);
- if ((token_positions != NULL) && (inlining_id < token_pos_map.Length())) {
- temp_smi ^= token_pos_map.At(inlining_id);
- token_positions->Add(TokenPosition(temp_smi.Value()));
- }
- inlining_id = caller_id;
- caller_id = GetCallerId(inlining_id);
- }
-}
-
-
-void Code::DumpInlinedIntervals() const {
- LogBlock lb;
- THR_Print("Inlined intervals:\n");
- const Array& intervals = Array::Handle(GetInlinedIntervals());
- if (intervals.IsNull() || (intervals.Length() == 0)) return;
- Smi& start = Smi::Handle();
- Smi& inlining_id = Smi::Handle();
- GrowableArray<Function*> inlined_functions;
- const Function& inliner = Function::Handle(function());
- for (intptr_t i = 0; i < intervals.Length(); i += Code::kInlIntNumEntries) {
- start ^= intervals.At(i + Code::kInlIntStart);
- ASSERT(!start.IsNull());
- if (start.IsNull()) continue;
- inlining_id ^= intervals.At(i + Code::kInlIntInliningId);
- THR_Print(" %" Px " iid: %" Pd " ; ", start.Value(), inlining_id.Value());
- inlined_functions.Clear();
-
- THR_Print("inlined: ");
- GetInlinedFunctionsAt(start.Value(), &inlined_functions);
-
- for (intptr_t j = 0; j < inlined_functions.length(); j++) {
- const char* name = inlined_functions[j]->ToQualifiedCString();
- THR_Print(" %s <-", name);
- }
- if (inlined_functions[inlined_functions.length() - 1]->raw() !=
- inliner.raw()) {
- THR_Print(" (ERROR, missing inliner)\n");
- } else {
- THR_Print("\n");
- }
- }
- THR_Print("Inlined ids:\n");
- const Array& id_map = Array::Handle(GetInlinedIdToFunction());
- Function& function = Function::Handle();
- for (intptr_t i = 0; i < id_map.Length(); i++) {
- function ^= id_map.At(i);
- if (!function.IsNull()) {
- THR_Print(" %" Pd ": %s\n", i, function.ToQualifiedCString());
- }
- }
- THR_Print("Inlined token pos:\n");
- const Array& token_pos_map = Array::Handle(GetInlinedIdToTokenPos());
- Smi& smi = Smi::Handle();
- for (intptr_t i = 0; i < token_pos_map.Length(); i++) {
- smi ^= token_pos_map.At(i);
- TokenPosition tp = TokenPosition(smi.Value());
- THR_Print(" %" Pd ": %s\n", i, tp.ToCString());
- }
- THR_Print("Caller Inlining Ids:\n");
- const Array& caller_map = Array::Handle(GetInlinedCallerIdMap());
- for (intptr_t i = 0; i < caller_map.Length(); i++) {
- smi ^= caller_map.At(i);
- THR_Print(" iid: %" Pd " caller iid: %" Pd "\n", i, smi.Value());
+
+void Code::DumpSourcePositions() const {
+ const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
+ if (map.IsNull()) {
+ // Stub code.
+ return;
}
+ const Array& id_map = Array::Handle(inlined_id_to_function());
+ const Function& root = Function::Handle(function());
+ CodeSourceMapReader reader(map, id_map, root);
+ reader.DumpSourcePositions(PayloadStart());
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698