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 10331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10342 // 4 bits per hex digit. | 10342 // 4 bits per hex digit. |
10343 const int addr_width = kBitsPerWord / 4; | 10343 const int addr_width = kBitsPerWord / 4; |
10344 // "*" in a printf format specifier tells it to read the field width from | 10344 // "*" in a printf format specifier tells it to read the field width from |
10345 // the printf argument list. | 10345 // the printf argument list. |
10346 const char* kFormat = | 10346 const char* kFormat = |
10347 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; | 10347 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; |
10348 // First compute the buffer size required. | 10348 // First compute the buffer size required. |
10349 intptr_t len = 1; // Trailing '\0'. | 10349 intptr_t len = 1; // Trailing '\0'. |
10350 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10350 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10351 while (iter.HasNext()) { | 10351 while (iter.HasNext()) { |
10352 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10352 RawPcDescriptors::PcDescriptorRec rec; |
| 10353 iter.NextRec(&rec); |
10353 len += OS::SNPrint(NULL, 0, kFormat, addr_width, | 10354 len += OS::SNPrint(NULL, 0, kFormat, addr_width, |
10354 rec.pc(), | 10355 rec.pc(), |
10355 KindAsStr(rec.kind()), | 10356 KindAsStr(rec.kind()), |
10356 rec.deopt_id(), | 10357 rec.deopt_id(), |
10357 rec.token_pos(), | 10358 rec.token_pos(), |
10358 rec.try_index()); | 10359 rec.try_index()); |
10359 } | 10360 } |
10360 // Allocate the buffer. | 10361 // Allocate the buffer. |
10361 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); | 10362 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); |
10362 // Layout the fields in the buffer. | 10363 // Layout the fields in the buffer. |
10363 intptr_t index = 0; | 10364 intptr_t index = 0; |
10364 Iterator iter2(*this, RawPcDescriptors::kAnyKind); | 10365 Iterator iter2(*this, RawPcDescriptors::kAnyKind); |
10365 while (iter2.HasNext()) { | 10366 while (iter2.HasNext()) { |
10366 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next(); | 10367 RawPcDescriptors::PcDescriptorRec rec; |
| 10368 iter2.NextRec(&rec); |
10367 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, | 10369 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, |
10368 rec.pc(), | 10370 rec.pc(), |
10369 KindAsStr(rec.kind()), | 10371 KindAsStr(rec.kind()), |
10370 rec.deopt_id(), | 10372 rec.deopt_id(), |
10371 rec.token_pos(), | 10373 rec.token_pos(), |
10372 rec.try_index()); | 10374 rec.try_index()); |
10373 } | 10375 } |
10374 return buffer; | 10376 return buffer; |
10375 } | 10377 } |
10376 | 10378 |
10377 | 10379 |
10378 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { | 10380 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { |
10379 jsobj->AddProperty("type", JSONType(false)); | 10381 jsobj->AddProperty("type", JSONType(false)); |
10380 // TODO(johnmccutchan): Generate a valid ID. | 10382 // TODO(johnmccutchan): Generate a valid ID. |
10381 // PcDescriptors hang off a Code object but do not have a back reference to | 10383 // PcDescriptors hang off a Code object but do not have a back reference to |
10382 // generate an ID. Currently we only print PcDescriptors inline with a Code. | 10384 // generate an ID. Currently we only print PcDescriptors inline with a Code. |
10383 jsobj->AddProperty("id", ""); | 10385 jsobj->AddProperty("id", ""); |
10384 JSONArray members(jsobj, "members"); | 10386 JSONArray members(jsobj, "members"); |
10385 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10387 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10386 while (iter.HasNext()) { | 10388 while (iter.HasNext()) { |
10387 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10389 RawPcDescriptors::PcDescriptorRec rec; |
| 10390 iter.NextRec(&rec); |
10388 JSONObject descriptor(&members); | 10391 JSONObject descriptor(&members); |
10389 descriptor.AddPropertyF("pc", "%" Px "", rec.pc()); | 10392 descriptor.AddPropertyF("pc", "%" Px "", rec.pc()); |
10390 descriptor.AddProperty("kind", KindAsStr(rec.kind())); | 10393 descriptor.AddProperty("kind", KindAsStr(rec.kind())); |
10391 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id())); | 10394 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id())); |
10392 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos())); | 10395 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos())); |
10393 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index())); | 10396 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index())); |
10394 } | 10397 } |
10395 } | 10398 } |
10396 | 10399 |
10397 | 10400 |
(...skipping 17 matching lines...) Expand all Loading... |
10415 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); | 10418 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); |
10416 } | 10419 } |
10417 return; | 10420 return; |
10418 } | 10421 } |
10419 // Only check ids for unoptimized code that is optimizable. | 10422 // Only check ids for unoptimized code that is optimizable. |
10420 if (!function.IsOptimizable()) { | 10423 if (!function.IsOptimizable()) { |
10421 return; | 10424 return; |
10422 } | 10425 } |
10423 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); | 10426 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); |
10424 while (iter.HasNext()) { | 10427 while (iter.HasNext()) { |
10425 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10428 RawPcDescriptors::PcDescriptorRec rec; |
10426 RawPcDescriptors::Kind kind = rec.kind(); | 10429 iter.NextRec(&rec); |
10427 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. | 10430 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. |
10428 intptr_t deopt_id = Isolate::kNoDeoptId; | |
10429 | 10431 |
10430 deopt_id = rec.deopt_id(); | 10432 if (Isolate::IsDeoptAfter(rec.deopt_id())) { |
10431 if (Isolate::IsDeoptAfter(deopt_id)) { | |
10432 // TODO(vegorov): some instructions contain multiple calls and have | 10433 // TODO(vegorov): some instructions contain multiple calls and have |
10433 // multiple "after" targets recorded. Right now it is benign but might | 10434 // multiple "after" targets recorded. Right now it is benign but might |
10434 // lead to issues in the future. Fix that and enable verification. | 10435 // lead to issues in the future. Fix that and enable verification. |
10435 continue; | 10436 continue; |
10436 } | 10437 } |
10437 | 10438 |
10438 Iterator nested(iter); | 10439 Iterator nested(iter); |
10439 while (nested.HasNext()) { | 10440 while (nested.HasNext()) { |
10440 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next(); | 10441 RawPcDescriptors::PcDescriptorRec nested_rec; |
10441 if (kind == nested_rec.kind()) { | 10442 nested.NextRec(&nested_rec); |
10442 if (deopt_id != Isolate::kNoDeoptId) { | 10443 if (rec.kind() == nested_rec.kind()) { |
10443 ASSERT(nested_rec.deopt_id() != deopt_id); | 10444 ASSERT(nested_rec.deopt_id() != rec.deopt_id()); |
10444 } | |
10445 } | 10445 } |
10446 } | 10446 } |
10447 } | 10447 } |
10448 #endif // DEBUG | 10448 #endif // DEBUG |
10449 } | 10449 } |
10450 | 10450 |
10451 | 10451 |
10452 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { | 10452 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { |
10453 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10453 Iterator iter(*this, kind); |
10454 while (iter.HasNext()) { | 10454 if (iter.HasNext()) { |
10455 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10455 return iter.NextPc(); |
10456 if (rec.kind() == kind) { | |
10457 return rec.pc(); | |
10458 } | |
10459 } | 10456 } |
10460 return 0; | 10457 return 0; |
10461 } | 10458 } |
10462 | 10459 |
10463 | 10460 |
10464 bool Stackmap::GetBit(intptr_t bit_index) const { | 10461 bool Stackmap::GetBit(intptr_t bit_index) const { |
10465 ASSERT(InRange(bit_index)); | 10462 ASSERT(InRange(bit_index)); |
10466 int byte_index = bit_index >> kBitsPerByteLog2; | 10463 int byte_index = bit_index >> kBitsPerByteLog2; |
10467 int bit_remainder = bit_index & (kBitsPerByte - 1); | 10464 int bit_remainder = bit_index & (kBitsPerByte - 1); |
10468 uint8_t byte_mask = 1U << bit_remainder; | 10465 uint8_t byte_mask = 1U << bit_remainder; |
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11947 return code.raw(); | 11944 return code.raw(); |
11948 } | 11945 } |
11949 return Code::null(); | 11946 return Code::null(); |
11950 } | 11947 } |
11951 | 11948 |
11952 | 11949 |
11953 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 11950 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
11954 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11951 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11955 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 11952 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
11956 while (iter.HasNext()) { | 11953 while (iter.HasNext()) { |
11957 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11954 RawPcDescriptors::PcDescriptorRec rec; |
| 11955 iter.NextRec(&rec); |
11958 if (rec.pc() == pc) { | 11956 if (rec.pc() == pc) { |
11959 return rec.token_pos(); | 11957 return rec.token_pos(); |
11960 } | 11958 } |
11961 } | 11959 } |
11962 return -1; | 11960 return -1; |
11963 } | 11961 } |
11964 | 11962 |
11965 | 11963 |
11966 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 11964 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
11967 RawPcDescriptors::Kind kind) const { | 11965 RawPcDescriptors::Kind kind) const { |
11968 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11966 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11969 PcDescriptors::Iterator iter(descriptors, kind); | 11967 PcDescriptors::Iterator iter(descriptors, kind); |
11970 while (iter.HasNext()) { | 11968 while (iter.HasNext()) { |
11971 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11969 RawPcDescriptors::PcDescriptorRec rec; |
| 11970 iter.NextRec(&rec); |
11972 if (rec.deopt_id() == deopt_id) { | 11971 if (rec.deopt_id() == deopt_id) { |
11973 uword pc = rec.pc(); | 11972 uword pc = rec.pc(); |
11974 ASSERT(ContainsInstructionAt(pc)); | 11973 ASSERT(ContainsInstructionAt(pc)); |
11975 return pc; | 11974 return pc; |
11976 } | 11975 } |
11977 } | 11976 } |
11978 return 0; | 11977 return 0; |
11979 } | 11978 } |
11980 | 11979 |
11981 | 11980 |
11982 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 11981 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
11983 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11982 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11984 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 11983 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
11985 while (iter.HasNext()) { | 11984 while (iter.HasNext()) { |
11986 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11985 RawPcDescriptors::PcDescriptorRec rec; |
| 11986 iter.NextRec(&rec); |
11987 if (rec.pc() == pc) { | 11987 if (rec.pc() == pc) { |
11988 return rec.deopt_id(); | 11988 return rec.deopt_id(); |
11989 } | 11989 } |
11990 } | 11990 } |
11991 return Isolate::kNoDeoptId; | 11991 return Isolate::kNoDeoptId; |
11992 } | 11992 } |
11993 | 11993 |
11994 | 11994 |
11995 const char* Code::ToCString() const { | 11995 const char* Code::ToCString() const { |
11996 const char* kFormat = "Code entry:%p"; | 11996 const char* kFormat = "Code entry:%p"; |
(...skipping 7168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19165 return tag_label.ToCString(); | 19165 return tag_label.ToCString(); |
19166 } | 19166 } |
19167 | 19167 |
19168 | 19168 |
19169 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19169 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
19170 Instance::PrintJSONImpl(stream, ref); | 19170 Instance::PrintJSONImpl(stream, ref); |
19171 } | 19171 } |
19172 | 19172 |
19173 | 19173 |
19174 } // namespace dart | 19174 } // namespace dart |
OLD | NEW |