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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 12078 matching lines...) Expand 10 before | Expand all | Expand 10 after
12089 deopt_ids->Add(iter.DeoptId()); 12089 deopt_ids->Add(iter.DeoptId());
12090 } else { 12090 } else {
12091 ASSERT(!iccall_ids->Contains(iter.DeoptId())); 12091 ASSERT(!iccall_ids->Contains(iter.DeoptId()));
12092 iccall_ids->Add(iter.DeoptId()); 12092 iccall_ids->Add(iter.DeoptId());
12093 } 12093 }
12094 } 12094 }
12095 #endif // DEBUG 12095 #endif // DEBUG
12096 } 12096 }
12097 12097
12098 12098
12099 TokenPosition CodeSourceMap::TokenPositionForPCOffset(uword pc_offset) const {
12100 Iterator iterator(*this);
12101
12102 TokenPosition result = TokenPosition::kNoSource;
12103
12104 while (iterator.MoveNext()) {
12105 if (iterator.PcOffset() > pc_offset) {
12106 break;
12107 }
12108 result = iterator.TokenPos();
12109 }
12110
12111 return result;
12112 }
12113
12114
12115 RawFunction* CodeSourceMap::FunctionForPCOffset(const Code& code,
12116 const Function& function,
12117 uword pc_offset) const {
12118 GrowableArray<Function*> inlined_functions;
12119 code.GetInlinedFunctionsAt(pc_offset, &inlined_functions);
12120 if (inlined_functions.length() > 0) {
12121 Function* inlined_function = inlined_functions[0];
12122 return inlined_function->raw();
12123 } else {
12124 return function.raw();
12125 }
12126 }
12127
12128
12129 RawScript* CodeSourceMap::ScriptForPCOffset(const Code& code,
12130 const Function& function,
12131 uword pc_offset) const {
12132 const Function& func =
12133 Function::Handle(FunctionForPCOffset(code, function, pc_offset));
12134 return func.script();
12135 }
12136
12137
12138 void CodeSourceMap::Dump(const CodeSourceMap& code_source_map,
12139 const Code& code,
12140 const Function& function) {
12141 const char* code_name = code.QualifiedName();
12142 THR_Print("Dumping Code Source Map for %s\n", code_name);
12143 if (code_source_map.Length() == 0) {
12144 THR_Print("<empty>\n");
12145 return;
12146 }
12147
12148 const int addr_width = kBitsPerWord / 4;
12149
12150 Iterator iterator(code_source_map);
12151 Function& current_function = Function::Handle();
12152 Script& current_script = Script::Handle();
12153 TokenPosition tp;
12154 while (iterator.MoveNext()) {
12155 const uword pc_offset = iterator.PcOffset();
12156 tp = code_source_map.TokenPositionForPCOffset(pc_offset);
12157 current_function ^=
12158 code_source_map.FunctionForPCOffset(code, function, pc_offset);
12159 current_script ^=
12160 code_source_map.ScriptForPCOffset(code, function, pc_offset);
12161 if (current_function.IsNull() || current_script.IsNull()) {
12162 THR_Print("%#-*" Px "\t%s\t%s\n", addr_width, pc_offset, tp.ToCString(),
12163 code_name);
12164 continue;
12165 }
12166 const String& uri = String::Handle(current_script.url());
12167 ASSERT(!uri.IsNull());
12168 THR_Print("%#-*" Px "\t%s\t%s\t%s\n", addr_width, pc_offset, tp.ToCString(),
12169 current_function.ToQualifiedCString(), uri.ToCString());
12170 }
12171 }
12172
12173
12174 intptr_t CodeSourceMap::Length() const {
12175 return raw_ptr()->length_;
12176 }
12177
12178
12179 void CodeSourceMap::SetLength(intptr_t value) const { 12099 void CodeSourceMap::SetLength(intptr_t value) const {
12180 StoreNonPointer(&raw_ptr()->length_, value); 12100 StoreNonPointer(&raw_ptr()->length_, value);
12181 } 12101 }
12182 12102
12183 12103
12184 void CodeSourceMap::CopyData(GrowableArray<uint8_t>* delta_encoded_data) {
12185 NoSafepointScope no_safepoint;
12186 uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]);
12187 for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) {
12188 data[i] = (*delta_encoded_data)[i];
12189 }
12190 }
12191
12192
12193 RawCodeSourceMap* CodeSourceMap::New(GrowableArray<uint8_t>* data) {
12194 ASSERT(Object::code_source_map_class() != Class::null());
12195 Thread* thread = Thread::Current();
12196 CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
12197 {
12198 uword size = CodeSourceMap::InstanceSize(data->length());
12199 RawObject* raw =
12200 Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
12201 NoSafepointScope no_safepoint;
12202 result ^= raw;
12203 result.SetLength(data->length());
12204 result.CopyData(data);
12205 }
12206 return result.raw();
12207 }
12208
12209
12210 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { 12104 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) {
12211 ASSERT(Object::code_source_map_class() != Class::null()); 12105 ASSERT(Object::code_source_map_class() != Class::null());
12212 Thread* thread = Thread::Current(); 12106 Thread* thread = Thread::Current();
12213 CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); 12107 CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
12214 { 12108 {
12215 uword size = CodeSourceMap::InstanceSize(length); 12109 uword size = CodeSourceMap::InstanceSize(length);
12216 RawObject* raw = 12110 RawObject* raw =
12217 Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld); 12111 Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
12218 NoSafepointScope no_safepoint; 12112 NoSafepointScope no_safepoint;
12219 result ^= raw; 12113 result ^= raw;
12220 result.SetLength(length); 12114 result.SetLength(length);
12221 } 12115 }
12222 return result.raw(); 12116 return result.raw();
12223 } 12117 }
12224 12118
12225 12119
12226 const char* CodeSourceMap::ToCString() const { 12120 const char* CodeSourceMap::ToCString() const {
12227 // "*" in a printf format specifier tells it to read the field width from 12121 return "CodeSourceMap";
12228 // the printf argument list.
12229 #define FORMAT "%#-*" Px "\t%s\n"
12230 if (Length() == 0) {
12231 return "empty CodeSourceMap\n";
12232 }
12233 // 4 bits per hex digit.
12234 const int addr_width = kBitsPerWord / 4;
12235 // First compute the buffer size required.
12236 intptr_t len = 1; // Trailing '\0'.
12237 {
12238 Iterator iter(*this);
12239 while (iter.MoveNext()) {
12240 len += OS::SNPrint(NULL, 0, FORMAT, addr_width, iter.PcOffset(),
12241 iter.TokenPos().ToCString());
12242 }
12243 }
12244 // Allocate the buffer.
12245 char* buffer = Thread::Current()->zone()->Alloc<char>(len);
12246 // Layout the fields in the buffer.
12247 intptr_t index = 0;
12248 Iterator iter(*this);
12249 while (iter.MoveNext()) {
12250 index += OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width,
12251 iter.PcOffset(), iter.TokenPos().ToCString());
12252 }
12253 return buffer;
12254 #undef FORMAT
12255 } 12122 }
12256 12123
12257 12124
12258 // Encode integer in SLEB128 format.
12259 void CodeSourceMap::EncodeInteger(GrowableArray<uint8_t>* data,
12260 intptr_t value) {
12261 return EncodeSLEB128(data, value);
12262 }
12263
12264
12265 // Decode SLEB128 encoded integer. Update byte_index to the next integer.
12266 intptr_t CodeSourceMap::DecodeInteger(intptr_t* byte_index) const {
12267 NoSafepointScope no_safepoint;
12268 const uint8_t* data = raw_ptr()->data();
12269 return DecodeSLEB128(data, Length(), byte_index);
12270 }
12271
12272
12273 bool StackMap::GetBit(intptr_t bit_index) const { 12125 bool StackMap::GetBit(intptr_t bit_index) const {
12274 ASSERT(InRange(bit_index)); 12126 ASSERT(InRange(bit_index));
12275 int byte_index = bit_index >> kBitsPerByteLog2; 12127 int byte_index = bit_index >> kBitsPerByteLog2;
12276 int bit_remainder = bit_index & (kBitsPerByte - 1); 12128 int bit_remainder = bit_index & (kBitsPerByte - 1);
12277 uint8_t byte_mask = 1U << bit_remainder; 12129 uint8_t byte_mask = 1U << bit_remainder;
12278 uint8_t byte = raw_ptr()->data()[byte_index]; 12130 uint8_t byte = raw_ptr()->data()[byte_index];
12279 return (byte & byte_mask); 12131 return (byte & byte_mask);
12280 } 12132 }
12281 12133
12282 12134
(...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after
14040 13892
14041 13893
14042 bool Code::HasBreakpoint() const { 13894 bool Code::HasBreakpoint() const {
14043 if (!FLAG_support_debugger) { 13895 if (!FLAG_support_debugger) {
14044 return false; 13896 return false;
14045 } 13897 }
14046 return Isolate::Current()->debugger()->HasBreakpoint(*this); 13898 return Isolate::Current()->debugger()->HasBreakpoint(*this);
14047 } 13899 }
14048 13900
14049 13901
14050 TokenPosition Code::GetTokenPositionAt(intptr_t offset) const {
14051 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14052 if (map.IsNull()) {
14053 return TokenPosition::kNoSource;
14054 }
14055 return map.TokenPositionForPCOffset(offset);
14056 }
14057
14058
14059 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, 13902 RawTypedData* Code::GetDeoptInfoAtPc(uword pc,
14060 ICData::DeoptReasonId* deopt_reason, 13903 ICData::DeoptReasonId* deopt_reason,
14061 uint32_t* deopt_flags) const { 13904 uint32_t* deopt_flags) const {
14062 ASSERT(is_optimized()); 13905 ASSERT(is_optimized());
14063 const Instructions& instrs = Instructions::Handle(instructions()); 13906 const Instructions& instrs = Instructions::Handle(instructions());
14064 uword code_entry = instrs.PayloadStart(); 13907 uword code_entry = instrs.PayloadStart();
14065 const Array& table = Array::Handle(deopt_info_array()); 13908 const Array& table = Array::Handle(deopt_info_array());
14066 if (table.IsNull()) { 13909 if (table.IsNull()) {
14067 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kAppAOT); 13910 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kAppAOT);
14068 return TypedData::null(); 13911 return TypedData::null();
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
14236 // In the future we may put something other than a smi in 14079 // In the future we may put something other than a smi in
14237 // |return_address_metadata_|. 14080 // |return_address_metadata_|.
14238 if (object.IsNull() || !object.IsSmi()) { 14081 if (object.IsNull() || !object.IsSmi()) {
14239 return -1; 14082 return -1;
14240 } 14083 }
14241 return Smi::Cast(object).Value(); 14084 return Smi::Cast(object).Value();
14242 #endif 14085 #endif
14243 } 14086 }
14244 14087
14245 14088
14246 RawArray* Code::GetInlinedIntervals() const { 14089 RawArray* Code::inlined_id_to_function() const {
14247 #if defined(DART_PRECOMPILED_RUNTIME) 14090 #if defined(DART_PRECOMPILED_RUNTIME)
14248 return Array::null(); 14091 return Array::null();
14249 #else 14092 #else
14250 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_); 14093 return raw_ptr()->inlined_id_to_function_;
14251 if (metadata.IsNull()) {
14252 return metadata.raw();
14253 }
14254 return reinterpret_cast<RawArray*>(
14255 metadata.At(RawCode::kInlinedIntervalsIndex));
14256 #endif 14094 #endif
14257 } 14095 }
14258 14096
14259 14097
14260 void Code::SetInlinedIntervals(const Array& value) const { 14098 void Code::set_inlined_id_to_function(const Array& value) const {
14261 #if defined(DART_PRECOMPILED_RUNTIME) 14099 #if defined(DART_PRECOMPILED_RUNTIME)
14262 UNREACHABLE(); 14100 UNREACHABLE();
14263 #else 14101 #else
14264 if (raw_ptr()->inlined_metadata_ == Array::null()) {
14265 StorePointer(&raw_ptr()->inlined_metadata_,
14266 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
14267 }
14268 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14269 ASSERT(!metadata.IsNull());
14270 ASSERT(metadata.IsOld());
14271 ASSERT(value.IsOld()); 14102 ASSERT(value.IsOld());
14272 metadata.SetAt(RawCode::kInlinedIntervalsIndex, value); 14103 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
14273 #endif 14104 #endif
14274 } 14105 }
14275 14106
14276
14277 RawArray* Code::GetInlinedIdToFunction() const {
14278 #if defined(DART_PRECOMPILED_RUNTIME)
14279 return Array::null();
14280 #else
14281 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14282 if (metadata.IsNull()) {
14283 return metadata.raw();
14284 }
14285 return reinterpret_cast<RawArray*>(
14286 metadata.At(RawCode::kInlinedIdToFunctionIndex));
14287 #endif
14288 }
14289
14290
14291 void Code::SetInlinedIdToFunction(const Array& value) const {
14292 #if defined(DART_PRECOMPILED_RUNTIME)
14293 UNREACHABLE();
14294 #else
14295 if (raw_ptr()->inlined_metadata_ == Array::null()) {
14296 StorePointer(&raw_ptr()->inlined_metadata_,
14297 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
14298 }
14299 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14300 ASSERT(!metadata.IsNull());
14301 ASSERT(metadata.IsOld());
14302 ASSERT(value.IsOld());
14303 metadata.SetAt(RawCode::kInlinedIdToFunctionIndex, value);
14304 #endif
14305 }
14306
14307
14308 RawArray* Code::GetInlinedIdToTokenPos() const {
14309 #if defined(DART_PRECOMPILED_RUNTIME)
14310 return Array::null();
14311 #else
14312 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14313 if (metadata.IsNull()) {
14314 return metadata.raw();
14315 }
14316 return reinterpret_cast<RawArray*>(
14317 metadata.At(RawCode::kInlinedIdToTokenPosIndex));
14318 #endif
14319 }
14320
14321
14322 void Code::SetInlinedIdToTokenPos(const Array& value) const {
14323 #if defined(DART_PRECOMPILED_RUNTIME)
14324 UNREACHABLE();
14325 #else
14326 if (raw_ptr()->inlined_metadata_ == Array::null()) {
14327 StorePointer(&raw_ptr()->inlined_metadata_,
14328 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
14329 }
14330 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14331 ASSERT(!metadata.IsNull());
14332 ASSERT(metadata.IsOld());
14333 ASSERT(value.IsOld());
14334 metadata.SetAt(RawCode::kInlinedIdToTokenPosIndex, value);
14335 #endif
14336 }
14337
14338
14339 RawArray* Code::GetInlinedCallerIdMap() const {
14340 #if defined(DART_PRECOMPILED_RUNTIME)
14341 return Array::null();
14342 #else
14343 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14344 if (metadata.IsNull()) {
14345 return metadata.raw();
14346 }
14347 return reinterpret_cast<RawArray*>(
14348 metadata.At(RawCode::kInlinedCallerIdMapIndex));
14349 #endif
14350 }
14351
14352
14353 void Code::SetInlinedCallerIdMap(const Array& value) const {
14354 #if defined(DART_PRECOMPILED_RUNTIME)
14355 UNREACHABLE();
14356 #else
14357 if (raw_ptr()->inlined_metadata_ == Array::null()) {
14358 StorePointer(&raw_ptr()->inlined_metadata_,
14359 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
14360 }
14361 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
14362 ASSERT(!metadata.IsNull());
14363 ASSERT(metadata.IsOld());
14364 ASSERT(value.IsOld());
14365 metadata.SetAt(RawCode::kInlinedCallerIdMapIndex, value);
14366 #endif
14367 }
14368
14369 14107
14370 RawCode* Code::New(intptr_t pointer_offsets_length) { 14108 RawCode* Code::New(intptr_t pointer_offsets_length) {
14371 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { 14109 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) {
14372 // This should be caught before we reach here. 14110 // This should be caught before we reach here.
14373 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", 14111 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n",
14374 pointer_offsets_length); 14112 pointer_offsets_length);
14375 } 14113 }
14376 ASSERT(Object::code_class() != Class::null()); 14114 ASSERT(Object::code_class() != Class::null());
14377 Code& result = Code::Handle(); 14115 Code& result = Code::Handle();
14378 { 14116 {
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
14715 // If we are missing a stack map, this must either be unoptimized code, or 14453 // If we are missing a stack map, this must either be unoptimized code, or
14716 // the entry to an osr function. (In which case all stack slots are 14454 // the entry to an osr function. (In which case all stack slots are
14717 // considered to have tagged pointers.) 14455 // considered to have tagged pointers.)
14718 // Running with --verify-on-transition should hit this. 14456 // Running with --verify-on-transition should hit this.
14719 ASSERT(!is_optimized() || 14457 ASSERT(!is_optimized() ||
14720 (pc_offset == UncheckedEntryPoint() - PayloadStart())); 14458 (pc_offset == UncheckedEntryPoint() - PayloadStart()));
14721 return StackMap::null(); 14459 return StackMap::null();
14722 } 14460 }
14723 14461
14724 14462
14725 intptr_t Code::GetCallerId(intptr_t inlined_id) const {
14726 if (inlined_id < 0) {
14727 return -1;
14728 }
14729 const Array& map = Array::Handle(GetInlinedCallerIdMap());
14730 if (map.IsNull() || (map.Length() == 0)) {
14731 return -1;
14732 }
14733 Smi& smi = Smi::Handle();
14734 smi ^= map.At(inlined_id);
14735 return smi.Value();
14736 }
14737
14738
14739 void Code::GetInlinedFunctionsAt( 14463 void Code::GetInlinedFunctionsAt(
14740 intptr_t offset, 14464 intptr_t pc_offset,
14741 GrowableArray<Function*>* fs, 14465 GrowableArray<const Function*>* functions,
14742 GrowableArray<TokenPosition>* token_positions) const { 14466 GrowableArray<TokenPosition>* token_positions) const {
14743 fs->Clear(); 14467 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14744 if (token_positions != NULL) { 14468 if (map.IsNull()) {
14745 token_positions->Clear(); 14469 // Stub code.
14746 }
14747 const Array& intervals = Array::Handle(GetInlinedIntervals());
14748 if (intervals.IsNull() || (intervals.Length() == 0)) {
14749 // E.g., for code stubs.
14750 return; 14470 return;
14751 } 14471 }
14752 // First find the right interval. TODO(srdjan): use binary search since 14472 const Array& id_map = Array::Handle(inlined_id_to_function());
14753 // intervals are sorted. 14473 const Function& root = Function::Handle(function());
14754 Smi& start = Smi::Handle(); 14474 CodeSourceMapReader reader(map, id_map, root);
14755 Smi& end = Smi::Handle(); 14475 reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions);
14756 intptr_t found_interval_ix = intervals.Length() - Code::kInlIntNumEntries;
14757 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries;
14758 i += Code::kInlIntNumEntries) {
14759 start ^= intervals.At(i + Code::kInlIntStart);
14760 if (!start.IsNull()) {
14761 end ^= intervals.At(i + Code::kInlIntNumEntries + Code::kInlIntStart);
14762 if ((start.Value() <= offset) && (offset < end.Value())) {
14763 found_interval_ix = i;
14764 break;
14765 }
14766 }
14767 }
14768
14769 // Find all functions.
14770 const Array& id_map = Array::Handle(GetInlinedIdToFunction());
14771 const Array& token_pos_map = Array::Handle(GetInlinedIdToTokenPos());
14772 Smi& temp_smi = Smi::Handle();
14773 temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntInliningId);
14774 intptr_t inlining_id = temp_smi.Value();
14775 ASSERT(inlining_id >= 0);
14776 intptr_t caller_id = GetCallerId(inlining_id);
14777 while (inlining_id >= 0) {
14778 Function& function = Function::ZoneHandle();
14779 function ^= id_map.At(inlining_id);
14780 fs->Add(&function);
14781 if ((token_positions != NULL) && (inlining_id < token_pos_map.Length())) {
14782 temp_smi ^= token_pos_map.At(inlining_id);
14783 token_positions->Add(TokenPosition(temp_smi.Value()));
14784 }
14785 inlining_id = caller_id;
14786 caller_id = GetCallerId(inlining_id);
14787 }
14788 } 14476 }
14789 14477
14790 14478
14791 void Code::DumpInlinedIntervals() const { 14479 #ifndef PRODUCT
14792 LogBlock lb; 14480 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const {
14793 THR_Print("Inlined intervals:\n"); 14481 if (!is_optimized()) {
14794 const Array& intervals = Array::Handle(GetInlinedIntervals()); 14482 return; // No inlining.
14795 if (intervals.IsNull() || (intervals.Length() == 0)) return; 14483 }
14796 Smi& start = Smi::Handle(); 14484 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14797 Smi& inlining_id = Smi::Handle(); 14485 const Array& id_map = Array::Handle(inlined_id_to_function());
14798 GrowableArray<Function*> inlined_functions; 14486 const Function& root = Function::Handle(function());
14799 const Function& inliner = Function::Handle(function()); 14487 CodeSourceMapReader reader(map, id_map, root);
14800 for (intptr_t i = 0; i < intervals.Length(); i += Code::kInlIntNumEntries) { 14488 reader.PrintJSONInlineIntervals(jsobj);
14801 start ^= intervals.At(i + Code::kInlIntStart); 14489 }
14802 ASSERT(!start.IsNull()); 14490 #endif
14803 if (start.IsNull()) continue;
14804 inlining_id ^= intervals.At(i + Code::kInlIntInliningId);
14805 THR_Print(" %" Px " iid: %" Pd " ; ", start.Value(), inlining_id.Value());
14806 inlined_functions.Clear();
14807 14491
14808 THR_Print("inlined: ");
14809 GetInlinedFunctionsAt(start.Value(), &inlined_functions);
14810 14492
14811 for (intptr_t j = 0; j < inlined_functions.length(); j++) { 14493 void Code::DumpInlineIntervals() const {
14812 const char* name = inlined_functions[j]->ToQualifiedCString(); 14494 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14813 THR_Print(" %s <-", name); 14495 if (map.IsNull()) {
14814 } 14496 // Stub code.
14815 if (inlined_functions[inlined_functions.length() - 1]->raw() != 14497 return;
14816 inliner.raw()) {
14817 THR_Print(" (ERROR, missing inliner)\n");
14818 } else {
14819 THR_Print("\n");
14820 }
14821 } 14498 }
14822 THR_Print("Inlined ids:\n"); 14499 const Array& id_map = Array::Handle(inlined_id_to_function());
14823 const Array& id_map = Array::Handle(GetInlinedIdToFunction()); 14500 const Function& root = Function::Handle(function());
14824 Function& function = Function::Handle(); 14501 CodeSourceMapReader reader(map, id_map, root);
14825 for (intptr_t i = 0; i < id_map.Length(); i++) { 14502 reader.DumpInlineIntervals(PayloadStart());
14826 function ^= id_map.At(i);
14827 if (!function.IsNull()) {
14828 THR_Print(" %" Pd ": %s\n", i, function.ToQualifiedCString());
14829 }
14830 }
14831 THR_Print("Inlined token pos:\n");
14832 const Array& token_pos_map = Array::Handle(GetInlinedIdToTokenPos());
14833 Smi& smi = Smi::Handle();
14834 for (intptr_t i = 0; i < token_pos_map.Length(); i++) {
14835 smi ^= token_pos_map.At(i);
14836 TokenPosition tp = TokenPosition(smi.Value());
14837 THR_Print(" %" Pd ": %s\n", i, tp.ToCString());
14838 }
14839 THR_Print("Caller Inlining Ids:\n");
14840 const Array& caller_map = Array::Handle(GetInlinedCallerIdMap());
14841 for (intptr_t i = 0; i < caller_map.Length(); i++) {
14842 smi ^= caller_map.At(i);
14843 THR_Print(" iid: %" Pd " caller iid: %" Pd "\n", i, smi.Value());
14844 }
14845 } 14503 }
14846 14504
14847 14505
14506 void Code::DumpSourcePositions() const {
14507 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map());
14508 if (map.IsNull()) {
14509 // Stub code.
14510 return;
14511 }
14512 const Array& id_map = Array::Handle(inlined_id_to_function());
14513 const Function& root = Function::Handle(function());
14514 CodeSourceMapReader reader(map, id_map, root);
14515 reader.DumpSourcePositions(PayloadStart());
14516 }
14517
14518
14848 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { 14519 RawContext* Context::New(intptr_t num_variables, Heap::Space space) {
14849 ASSERT(num_variables >= 0); 14520 ASSERT(num_variables >= 0);
14850 ASSERT(Object::context_class() != Class::null()); 14521 ASSERT(Object::context_class() != Class::null());
14851 14522
14852 if (num_variables < 0 || num_variables > kMaxElements) { 14523 if (num_variables < 0 || num_variables > kMaxElements) {
14853 // This should be caught before we reach here. 14524 // This should be caught before we reach here.
14854 FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n", 14525 FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n",
14855 num_variables); 14526 num_variables);
14856 } 14527 }
14857 Context& result = Context::Handle(); 14528 Context& result = Context::Handle();
(...skipping 8230 matching lines...) Expand 10 before | Expand all | Expand 10 after
23088 return UserTag::null(); 22759 return UserTag::null();
23089 } 22760 }
23090 22761
23091 22762
23092 const char* UserTag::ToCString() const { 22763 const char* UserTag::ToCString() const {
23093 const String& tag_label = String::Handle(label()); 22764 const String& tag_label = String::Handle(label());
23094 return tag_label.ToCString(); 22765 return tag_label.ToCString();
23095 } 22766 }
23096 22767
23097 } // namespace dart 22768 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698