| 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 10187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10198 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { | 10198 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { |
| 10199 switch (kind) { | 10199 switch (kind) { |
| 10200 case RawPcDescriptors::kDeopt: return "deopt "; | 10200 case RawPcDescriptors::kDeopt: return "deopt "; |
| 10201 case RawPcDescriptors::kIcCall: return "ic-call "; | 10201 case RawPcDescriptors::kIcCall: return "ic-call "; |
| 10202 case RawPcDescriptors::kOptStaticCall: return "opt-call "; | 10202 case RawPcDescriptors::kOptStaticCall: return "opt-call "; |
| 10203 case RawPcDescriptors::kUnoptStaticCall: return "unopt-call "; | 10203 case RawPcDescriptors::kUnoptStaticCall: return "unopt-call "; |
| 10204 case RawPcDescriptors::kClosureCall: return "closure-call "; | 10204 case RawPcDescriptors::kClosureCall: return "closure-call "; |
| 10205 case RawPcDescriptors::kRuntimeCall: return "runtime-call "; | 10205 case RawPcDescriptors::kRuntimeCall: return "runtime-call "; |
| 10206 case RawPcDescriptors::kOsrEntry: return "osr-entry "; | 10206 case RawPcDescriptors::kOsrEntry: return "osr-entry "; |
| 10207 case RawPcDescriptors::kOther: return "other "; | 10207 case RawPcDescriptors::kOther: return "other "; |
| 10208 case RawPcDescriptors::kAnyKind: UNREACHABLE(); break; |
| 10208 } | 10209 } |
| 10209 UNREACHABLE(); | 10210 UNREACHABLE(); |
| 10210 return ""; | 10211 return ""; |
| 10211 } | 10212 } |
| 10212 | 10213 |
| 10213 | 10214 |
| 10214 void PcDescriptors::PrintHeaderString() { | 10215 void PcDescriptors::PrintHeaderString() { |
| 10215 // 4 bits per hex digit + 2 for "0x". | 10216 // 4 bits per hex digit + 2 for "0x". |
| 10216 const int addr_width = (kBitsPerWord / 4) + 2; | 10217 const int addr_width = (kBitsPerWord / 4) + 2; |
| 10217 // "*" in a printf format specifier tells it to read the field width from | 10218 // "*" in a printf format specifier tells it to read the field width from |
| 10218 // the printf argument list. | 10219 // the printf argument list. |
| 10219 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", | 10220 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", |
| 10220 addr_width, "pc"); | 10221 addr_width, "pc"); |
| 10221 } | 10222 } |
| 10222 | 10223 |
| 10223 | 10224 |
| 10224 const char* PcDescriptors::ToCString() const { | 10225 const char* PcDescriptors::ToCString() const { |
| 10225 if (Length() == 0) { | 10226 if (Length() == 0) { |
| 10226 return "No pc descriptors\n"; | 10227 return "No pc descriptors\n"; |
| 10227 } | 10228 } |
| 10228 // 4 bits per hex digit. | 10229 // 4 bits per hex digit. |
| 10229 const int addr_width = kBitsPerWord / 4; | 10230 const int addr_width = kBitsPerWord / 4; |
| 10230 // "*" in a printf format specifier tells it to read the field width from | 10231 // "*" in a printf format specifier tells it to read the field width from |
| 10231 // the printf argument list. | 10232 // the printf argument list. |
| 10232 const char* kFormat = | 10233 const char* kFormat = |
| 10233 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; | 10234 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; |
| 10234 // First compute the buffer size required. | 10235 // First compute the buffer size required. |
| 10235 intptr_t len = 1; // Trailing '\0'. | 10236 intptr_t len = 1; // Trailing '\0'. |
| 10236 Iterator iter(*this); | 10237 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
| 10237 while (iter.HasNext()) { | 10238 while (iter.HasNext()) { |
| 10238 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10239 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 10239 len += OS::SNPrint(NULL, 0, kFormat, addr_width, | 10240 len += OS::SNPrint(NULL, 0, kFormat, addr_width, |
| 10240 rec.pc, | 10241 rec.pc, |
| 10241 KindAsStr(rec.kind()), | 10242 KindAsStr(rec.kind()), |
| 10242 rec.deopt_id, | 10243 rec.deopt_id, |
| 10243 rec.token_pos, | 10244 rec.token_pos, |
| 10244 rec.try_index); | 10245 rec.try_index); |
| 10245 } | 10246 } |
| 10246 // Allocate the buffer. | 10247 // Allocate the buffer. |
| 10247 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); | 10248 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 10248 // Layout the fields in the buffer. | 10249 // Layout the fields in the buffer. |
| 10249 intptr_t index = 0; | 10250 intptr_t index = 0; |
| 10250 Iterator iter2(*this); | 10251 Iterator iter2(*this, RawPcDescriptors::kAnyKind); |
| 10251 while (iter2.HasNext()) { | 10252 while (iter2.HasNext()) { |
| 10252 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next(); | 10253 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next(); |
| 10253 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, | 10254 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, |
| 10254 rec.pc, | 10255 rec.pc, |
| 10255 KindAsStr(rec.kind()), | 10256 KindAsStr(rec.kind()), |
| 10256 rec.deopt_id, | 10257 rec.deopt_id, |
| 10257 rec.token_pos, | 10258 rec.token_pos, |
| 10258 rec.try_index); | 10259 rec.try_index); |
| 10259 } | 10260 } |
| 10260 return buffer; | 10261 return buffer; |
| 10261 } | 10262 } |
| 10262 | 10263 |
| 10263 | 10264 |
| 10264 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { | 10265 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { |
| 10265 jsobj->AddProperty("type", JSONType(false)); | 10266 jsobj->AddProperty("type", JSONType(false)); |
| 10266 // TODO(johnmccutchan): Generate a valid ID. | 10267 // TODO(johnmccutchan): Generate a valid ID. |
| 10267 // PcDescriptors hang off a Code object but do not have a back reference to | 10268 // PcDescriptors hang off a Code object but do not have a back reference to |
| 10268 // generate an ID. Currently we only print PcDescriptors inline with a Code. | 10269 // generate an ID. Currently we only print PcDescriptors inline with a Code. |
| 10269 jsobj->AddProperty("id", ""); | 10270 jsobj->AddProperty("id", ""); |
| 10270 JSONArray members(jsobj, "members"); | 10271 JSONArray members(jsobj, "members"); |
| 10271 Iterator iter(*this); | 10272 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
| 10272 while (iter.HasNext()) { | 10273 while (iter.HasNext()) { |
| 10273 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10274 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 10274 JSONObject descriptor(&members); | 10275 JSONObject descriptor(&members); |
| 10275 descriptor.AddPropertyF("pc", "%" Px "", rec.pc); | 10276 descriptor.AddPropertyF("pc", "%" Px "", rec.pc); |
| 10276 descriptor.AddProperty("kind", KindAsStr(rec.kind())); | 10277 descriptor.AddProperty("kind", KindAsStr(rec.kind())); |
| 10277 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id)); | 10278 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id)); |
| 10278 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos)); | 10279 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos)); |
| 10279 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index)); | 10280 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index)); |
| 10280 } | 10281 } |
| 10281 } | 10282 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 10299 if (Length() > 3000) { | 10300 if (Length() > 3000) { |
| 10300 if (FLAG_trace_compiler) { | 10301 if (FLAG_trace_compiler) { |
| 10301 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); | 10302 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); |
| 10302 } | 10303 } |
| 10303 return; | 10304 return; |
| 10304 } | 10305 } |
| 10305 // Only check ids for unoptimized code that is optimizable. | 10306 // Only check ids for unoptimized code that is optimizable. |
| 10306 if (!function.IsOptimizable()) { | 10307 if (!function.IsOptimizable()) { |
| 10307 return; | 10308 return; |
| 10308 } | 10309 } |
| 10309 Iterator iter(*this); | 10310 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); |
| 10310 while (iter.HasNext()) { | 10311 while (iter.HasNext()) { |
| 10311 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10312 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 10312 RawPcDescriptors::Kind kind = rec.kind(); | 10313 RawPcDescriptors::Kind kind = rec.kind(); |
| 10313 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. | 10314 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. |
| 10314 intptr_t deopt_id = Isolate::kNoDeoptId; | 10315 intptr_t deopt_id = Isolate::kNoDeoptId; |
| 10315 if ((kind != RawPcDescriptors::kDeopt) || | |
| 10316 (kind != RawPcDescriptors::kIcCall)) { | |
| 10317 continue; | |
| 10318 } | |
| 10319 | 10316 |
| 10320 deopt_id = rec.deopt_id; | 10317 deopt_id = rec.deopt_id; |
| 10321 if (Isolate::IsDeoptAfter(deopt_id)) { | 10318 if (Isolate::IsDeoptAfter(deopt_id)) { |
| 10322 // TODO(vegorov): some instructions contain multiple calls and have | 10319 // TODO(vegorov): some instructions contain multiple calls and have |
| 10323 // multiple "after" targets recorded. Right now it is benign but might | 10320 // multiple "after" targets recorded. Right now it is benign but might |
| 10324 // lead to issues in the future. Fix that and enable verification. | 10321 // lead to issues in the future. Fix that and enable verification. |
| 10325 continue; | 10322 continue; |
| 10326 } | 10323 } |
| 10327 | 10324 |
| 10328 Iterator nested(iter); | 10325 Iterator nested(iter); |
| 10329 while (iter.HasNext()) { | 10326 while (nested.HasNext()) { |
| 10330 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next(); | 10327 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next(); |
| 10331 if (kind == nested_rec.kind()) { | 10328 if (kind == nested_rec.kind()) { |
| 10332 if (deopt_id != Isolate::kNoDeoptId) { | 10329 if (deopt_id != Isolate::kNoDeoptId) { |
| 10333 ASSERT(nested_rec.deopt_id != deopt_id); | 10330 ASSERT(nested_rec.deopt_id != deopt_id); |
| 10334 } | 10331 } |
| 10335 } | 10332 } |
| 10336 } | 10333 } |
| 10337 } | 10334 } |
| 10338 #endif // DEBUG | 10335 #endif // DEBUG |
| 10339 } | 10336 } |
| 10340 | 10337 |
| 10341 | 10338 |
| 10342 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { | 10339 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { |
| 10343 Iterator iter(*this); | 10340 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
| 10344 while (iter.HasNext()) { | 10341 while (iter.HasNext()) { |
| 10345 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10342 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 10346 if (rec.kind() == kind) { | 10343 if (rec.kind() == kind) { |
| 10347 return rec.pc; | 10344 return rec.pc; |
| 10348 } | 10345 } |
| 10349 } | 10346 } |
| 10350 return 0; | 10347 return 0; |
| 10351 } | 10348 } |
| 10352 | 10349 |
| 10353 | 10350 |
| (...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11835 (code.EntryPoint() == pc)) { | 11832 (code.EntryPoint() == pc)) { |
| 11836 // Found code in VM isolate. | 11833 // Found code in VM isolate. |
| 11837 return code.raw(); | 11834 return code.raw(); |
| 11838 } | 11835 } |
| 11839 return Code::null(); | 11836 return Code::null(); |
| 11840 } | 11837 } |
| 11841 | 11838 |
| 11842 | 11839 |
| 11843 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 11840 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
| 11844 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11841 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 11845 PcDescriptors::Iterator iter(descriptors); | 11842 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
| 11846 while (iter.HasNext()) { | 11843 while (iter.HasNext()) { |
| 11847 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11844 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 11848 if (rec.pc == pc) { | 11845 if (rec.pc == pc) { |
| 11849 return rec.token_pos; | 11846 return rec.token_pos; |
| 11850 } | 11847 } |
| 11851 } | 11848 } |
| 11852 return -1; | 11849 return -1; |
| 11853 } | 11850 } |
| 11854 | 11851 |
| 11855 | 11852 |
| 11856 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 11853 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
| 11857 RawPcDescriptors::Kind kind) const { | 11854 RawPcDescriptors::Kind kind) const { |
| 11858 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11855 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 11859 PcDescriptors::Iterator iter(descriptors); | 11856 PcDescriptors::Iterator iter(descriptors, kind); |
| 11860 while (iter.HasNext()) { | 11857 while (iter.HasNext()) { |
| 11861 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11858 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 11862 if ((rec.deopt_id == deopt_id) && (rec.kind() == kind)) { | 11859 if (rec.deopt_id == deopt_id) { |
| 11863 uword pc = rec.pc; | 11860 uword pc = rec.pc; |
| 11864 ASSERT(ContainsInstructionAt(pc)); | 11861 ASSERT(ContainsInstructionAt(pc)); |
| 11865 return pc; | 11862 return pc; |
| 11866 } | 11863 } |
| 11867 } | 11864 } |
| 11868 return 0; | 11865 return 0; |
| 11869 } | 11866 } |
| 11870 | 11867 |
| 11871 | 11868 |
| 11872 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 11869 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
| 11873 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11870 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 11874 PcDescriptors::Iterator iter(descriptors); | 11871 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
| 11875 while (iter.HasNext()) { | 11872 while (iter.HasNext()) { |
| 11876 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11873 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
| 11877 if ((rec.pc == pc) && (rec.kind() == RawPcDescriptors::kOsrEntry)) { | 11874 if (rec.pc == pc) { |
| 11878 return rec.deopt_id; | 11875 return rec.deopt_id; |
| 11879 } | 11876 } |
| 11880 } | 11877 } |
| 11881 return Isolate::kNoDeoptId; | 11878 return Isolate::kNoDeoptId; |
| 11882 } | 11879 } |
| 11883 | 11880 |
| 11884 | 11881 |
| 11885 const char* Code::ToCString() const { | 11882 const char* Code::ToCString() const { |
| 11886 const char* kFormat = "Code entry:%p"; | 11883 const char* kFormat = "Code entry:%p"; |
| 11887 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; | 11884 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; |
| (...skipping 7166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19054 return tag_label.ToCString(); | 19051 return tag_label.ToCString(); |
| 19055 } | 19052 } |
| 19056 | 19053 |
| 19057 | 19054 |
| 19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19055 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 19059 Instance::PrintJSONImpl(stream, ref); | 19056 Instance::PrintJSONImpl(stream, ref); |
| 19060 } | 19057 } |
| 19061 | 19058 |
| 19062 | 19059 |
| 19063 } // namespace dart | 19060 } // namespace dart |
| OLD | NEW |