OLD | NEW |
---|---|
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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 10340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10351 } | 10351 } |
10352 // 4 bits per hex digit. | 10352 // 4 bits per hex digit. |
10353 const int addr_width = kBitsPerWord / 4; | 10353 const int addr_width = kBitsPerWord / 4; |
10354 // "*" in a printf format specifier tells it to read the field width from | 10354 // "*" in a printf format specifier tells it to read the field width from |
10355 // the printf argument list. | 10355 // the printf argument list. |
10356 const char* kFormat = | 10356 const char* kFormat = |
10357 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; | 10357 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; |
10358 // First compute the buffer size required. | 10358 // First compute the buffer size required. |
10359 intptr_t len = 1; // Trailing '\0'. | 10359 intptr_t len = 1; // Trailing '\0'. |
10360 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10360 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10361 while (iter.HasNext()) { | 10361 while (iter.HasNext()) { |
hausner
2014/07/17 23:22:56
See other comment. This loop would become:
while
srdjan
2014/07/18 18:16:45
Good suggestion, changed to:
while (iter.MoveNext
| |
10362 RawPcDescriptors::PcDescriptorRec rec; | 10362 uword pc = iter.NextPc(); |
10363 iter.NextRec(&rec); | |
10364 len += OS::SNPrint(NULL, 0, kFormat, addr_width, | 10363 len += OS::SNPrint(NULL, 0, kFormat, addr_width, |
10365 rec.pc(), | 10364 pc, |
10366 KindAsStr(rec.kind()), | 10365 KindAsStr(iter.current_kind()), |
10367 rec.deopt_id(), | 10366 iter.current_deopt_id(), |
10368 rec.token_pos(), | 10367 iter.current_token_pos(), |
10369 rec.try_index()); | 10368 iter.current_try_index()); |
10370 } | 10369 } |
10371 // Allocate the buffer. | 10370 // Allocate the buffer. |
10372 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); | 10371 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); |
10373 // Layout the fields in the buffer. | 10372 // Layout the fields in the buffer. |
10374 intptr_t index = 0; | 10373 intptr_t index = 0; |
10375 Iterator iter2(*this, RawPcDescriptors::kAnyKind); | 10374 Iterator iter2(*this, RawPcDescriptors::kAnyKind); |
10376 while (iter2.HasNext()) { | 10375 while (iter2.HasNext()) { |
10377 RawPcDescriptors::PcDescriptorRec rec; | 10376 uword pc = iter2.NextPc(); |
10378 iter2.NextRec(&rec); | |
10379 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, | 10377 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, |
10380 rec.pc(), | 10378 pc, |
10381 KindAsStr(rec.kind()), | 10379 KindAsStr(iter.current_kind()), |
10382 rec.deopt_id(), | 10380 iter.current_deopt_id(), |
10383 rec.token_pos(), | 10381 iter.current_token_pos(), |
10384 rec.try_index()); | 10382 iter.current_try_index()); |
10385 } | 10383 } |
10386 return buffer; | 10384 return buffer; |
10387 } | 10385 } |
10388 | 10386 |
10389 | 10387 |
10390 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { | 10388 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { |
10391 jsobj->AddProperty("type", JSONType(false)); | 10389 jsobj->AddProperty("type", JSONType(false)); |
10392 // TODO(johnmccutchan): Generate a valid ID. | 10390 // TODO(johnmccutchan): Generate a valid ID. |
10393 // PcDescriptors hang off a Code object but do not have a back reference to | 10391 // PcDescriptors hang off a Code object but do not have a back reference to |
10394 // generate an ID. Currently we only print PcDescriptors inline with a Code. | 10392 // generate an ID. Currently we only print PcDescriptors inline with a Code. |
10395 jsobj->AddProperty("id", ""); | 10393 jsobj->AddProperty("id", ""); |
10396 JSONArray members(jsobj, "members"); | 10394 JSONArray members(jsobj, "members"); |
10397 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10395 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10398 while (iter.HasNext()) { | 10396 while (iter.HasNext()) { |
10399 RawPcDescriptors::PcDescriptorRec rec; | 10397 uword pc = iter.NextPc(); |
10400 iter.NextRec(&rec); | |
10401 JSONObject descriptor(&members); | 10398 JSONObject descriptor(&members); |
10402 descriptor.AddPropertyF("pc", "%" Px "", rec.pc()); | 10399 descriptor.AddPropertyF("pc", "%" Px "", pc); |
10403 descriptor.AddProperty("kind", KindAsStr(rec.kind())); | 10400 descriptor.AddProperty("kind", KindAsStr(iter.current_kind())); |
10404 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id())); | 10401 descriptor.AddProperty("deoptId", iter.current_deopt_id()); |
10405 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos())); | 10402 descriptor.AddProperty("tokenPos", iter.current_token_pos()); |
10406 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index())); | 10403 descriptor.AddProperty("tryIndex", iter.current_try_index()); |
10407 } | 10404 } |
10408 } | 10405 } |
10409 | 10406 |
10410 | 10407 |
10411 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { | 10408 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { |
10412 JSONObject jsobj(stream); | 10409 JSONObject jsobj(stream); |
10413 PrintToJSONObject(&jsobj); | 10410 PrintToJSONObject(&jsobj); |
10414 } | 10411 } |
10415 | 10412 |
10416 | 10413 |
(...skipping 11 matching lines...) Expand all Loading... | |
10428 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); | 10425 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); |
10429 } | 10426 } |
10430 return; | 10427 return; |
10431 } | 10428 } |
10432 // Only check ids for unoptimized code that is optimizable. | 10429 // Only check ids for unoptimized code that is optimizable. |
10433 if (!function.IsOptimizable()) { | 10430 if (!function.IsOptimizable()) { |
10434 return; | 10431 return; |
10435 } | 10432 } |
10436 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); | 10433 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); |
10437 while (iter.HasNext()) { | 10434 while (iter.HasNext()) { |
10438 RawPcDescriptors::PcDescriptorRec rec; | 10435 const intptr_t deopt_id = iter.NextDeoptId(); |
10439 iter.NextRec(&rec); | |
10440 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. | 10436 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. |
10441 | 10437 |
10442 if (Isolate::IsDeoptAfter(rec.deopt_id())) { | 10438 if (Isolate::IsDeoptAfter(deopt_id)) { |
10443 // TODO(vegorov): some instructions contain multiple calls and have | 10439 // TODO(vegorov): some instructions contain multiple calls and have |
10444 // multiple "after" targets recorded. Right now it is benign but might | 10440 // multiple "after" targets recorded. Right now it is benign but might |
10445 // lead to issues in the future. Fix that and enable verification. | 10441 // lead to issues in the future. Fix that and enable verification. |
10446 continue; | 10442 continue; |
10447 } | 10443 } |
10448 | 10444 |
10449 Iterator nested(iter); | 10445 Iterator nested(iter); |
10450 while (nested.HasNext()) { | 10446 while (nested.HasNext()) { |
10451 RawPcDescriptors::PcDescriptorRec nested_rec; | 10447 intptr_t nested_deopt_id = nested.NextDeoptId(); |
10452 nested.NextRec(&nested_rec); | 10448 if (iter.current_kind() == nested.current_kind()) { |
10453 if (rec.kind() == nested_rec.kind()) { | 10449 ASSERT(nested_deopt_id != iter.current_deopt_id()); |
10454 ASSERT(nested_rec.deopt_id() != rec.deopt_id()); | |
10455 } | 10450 } |
10456 } | 10451 } |
10457 } | 10452 } |
10458 #endif // DEBUG | 10453 #endif // DEBUG |
10459 } | 10454 } |
10460 | 10455 |
10461 | 10456 |
10462 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { | 10457 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { |
10463 Iterator iter(*this, kind); | 10458 Iterator iter(*this, kind); |
10464 if (iter.HasNext()) { | 10459 if (iter.HasNext()) { |
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11954 return code.raw(); | 11949 return code.raw(); |
11955 } | 11950 } |
11956 return Code::null(); | 11951 return Code::null(); |
11957 } | 11952 } |
11958 | 11953 |
11959 | 11954 |
11960 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 11955 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
11961 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11956 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11962 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 11957 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
11963 while (iter.HasNext()) { | 11958 while (iter.HasNext()) { |
11964 RawPcDescriptors::PcDescriptorRec rec; | 11959 const uword current_pc = iter.NextPc(); |
11965 iter.NextRec(&rec); | 11960 if (current_pc == pc) { |
11966 if (rec.pc() == pc) { | 11961 return iter.current_token_pos(); |
11967 return rec.token_pos(); | |
11968 } | 11962 } |
11969 } | 11963 } |
11970 return -1; | 11964 return -1; |
11971 } | 11965 } |
11972 | 11966 |
11973 | 11967 |
11974 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 11968 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
11975 RawPcDescriptors::Kind kind) const { | 11969 RawPcDescriptors::Kind kind) const { |
11976 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11970 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11977 PcDescriptors::Iterator iter(descriptors, kind); | 11971 PcDescriptors::Iterator iter(descriptors, kind); |
11978 while (iter.HasNext()) { | 11972 while (iter.HasNext()) { |
11979 RawPcDescriptors::PcDescriptorRec rec; | 11973 const intptr_t current_deopt_id = iter.NextDeoptId(); |
11980 iter.NextRec(&rec); | 11974 if (current_deopt_id == deopt_id) { |
11981 if (rec.deopt_id() == deopt_id) { | 11975 uword pc = iter.current_pc(); |
11982 uword pc = rec.pc(); | |
11983 ASSERT(ContainsInstructionAt(pc)); | 11976 ASSERT(ContainsInstructionAt(pc)); |
11984 return pc; | 11977 return pc; |
11985 } | 11978 } |
11986 } | 11979 } |
11987 return 0; | 11980 return 0; |
11988 } | 11981 } |
11989 | 11982 |
11990 | 11983 |
11991 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 11984 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
11992 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11985 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11993 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 11986 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
11994 while (iter.HasNext()) { | 11987 while (iter.HasNext()) { |
11995 RawPcDescriptors::PcDescriptorRec rec; | 11988 const uword current_pc = iter.NextPc(); |
11996 iter.NextRec(&rec); | 11989 if (current_pc == pc) { |
11997 if (rec.pc() == pc) { | 11990 return iter.current_deopt_id(); |
11998 return rec.deopt_id(); | |
11999 } | 11991 } |
12000 } | 11992 } |
12001 return Isolate::kNoDeoptId; | 11993 return Isolate::kNoDeoptId; |
12002 } | 11994 } |
12003 | 11995 |
12004 | 11996 |
12005 const char* Code::ToCString() const { | 11997 const char* Code::ToCString() const { |
12006 const char* kFormat = "Code entry:%p"; | 11998 const char* kFormat = "Code entry:%p"; |
12007 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; | 11999 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; |
12008 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 12000 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
(...skipping 7166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
19175 return tag_label.ToCString(); | 19167 return tag_label.ToCString(); |
19176 } | 19168 } |
19177 | 19169 |
19178 | 19170 |
19179 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19171 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
19180 Instance::PrintJSONImpl(stream, ref); | 19172 Instance::PrintJSONImpl(stream, ref); |
19181 } | 19173 } |
19182 | 19174 |
19183 | 19175 |
19184 } // namespace dart | 19176 } // namespace dart |
OLD | NEW |