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