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 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 InitializeObject(address, kArrayCid, Array::InstanceSize(1)); | 653 InitializeObject(address, kArrayCid, Array::InstanceSize(1)); |
654 Array::initializeHandle( | 654 Array::initializeHandle( |
655 zero_array_, | 655 zero_array_, |
656 reinterpret_cast<RawArray*>(address + kHeapObjectTag)); | 656 reinterpret_cast<RawArray*>(address + kHeapObjectTag)); |
657 zero_array_->raw_ptr()->length_ = Smi::New(1); | 657 zero_array_->raw_ptr()->length_ = Smi::New(1); |
658 zero_array_->raw_ptr()->data()[0] = Smi::New(0); | 658 zero_array_->raw_ptr()->data()[0] = Smi::New(0); |
659 } | 659 } |
660 | 660 |
661 // Allocate and initialize the empty_descriptors instance. | 661 // Allocate and initialize the empty_descriptors instance. |
662 { | 662 { |
663 uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); | 663 uword address = heap->Allocate( |
| 664 PcDescriptors::InstanceSize(0, RawPcDescriptors::kCompressedRecSize), |
| 665 Heap::kOld); |
664 InitializeObject(address, kPcDescriptorsCid, | 666 InitializeObject(address, kPcDescriptorsCid, |
665 PcDescriptors::InstanceSize(0)); | 667 PcDescriptors::InstanceSize(0, RawPcDescriptors::kCompressedRecSize)); |
666 PcDescriptors::initializeHandle( | 668 PcDescriptors::initializeHandle( |
667 empty_descriptors_, | 669 empty_descriptors_, |
668 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag)); | 670 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag)); |
669 empty_descriptors_->raw_ptr()->length_ = 0; | 671 empty_descriptors_->raw_ptr()->length_ = 0; |
670 } | 672 } |
671 | 673 |
672 | 674 |
673 cls = Class::New<Instance>(kDynamicCid); | 675 cls = Class::New<Instance>(kDynamicCid); |
674 cls.set_is_abstract(); | 676 cls.set_is_abstract(); |
675 cls.set_num_type_arguments(0); | 677 cls.set_num_type_arguments(0); |
(...skipping 9536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10212 intptr_t PcDescriptors::Length() const { | 10214 intptr_t PcDescriptors::Length() const { |
10213 return raw_ptr()->length_; | 10215 return raw_ptr()->length_; |
10214 } | 10216 } |
10215 | 10217 |
10216 | 10218 |
10217 void PcDescriptors::SetLength(intptr_t value) const { | 10219 void PcDescriptors::SetLength(intptr_t value) const { |
10218 raw_ptr()->length_ = value; | 10220 raw_ptr()->length_ = value; |
10219 } | 10221 } |
10220 | 10222 |
10221 | 10223 |
10222 RawPcDescriptors* PcDescriptors::New(intptr_t num_descriptors) { | 10224 intptr_t PcDescriptors::RecordSizeInBytes() const { |
| 10225 return raw_ptr()->record_size_in_bytes_; |
| 10226 } |
| 10227 |
| 10228 |
| 10229 void PcDescriptors::SetRecordSizeInBytes(intptr_t value) const { |
| 10230 raw_ptr()->record_size_in_bytes_ = value; |
| 10231 } |
| 10232 |
| 10233 |
| 10234 RawPcDescriptors* PcDescriptors::New(intptr_t num_descriptors, |
| 10235 bool has_try_index) { |
10223 ASSERT(Object::pc_descriptors_class() != Class::null()); | 10236 ASSERT(Object::pc_descriptors_class() != Class::null()); |
10224 if (num_descriptors < 0 || num_descriptors > kMaxElements) { | 10237 if (num_descriptors < 0 || num_descriptors > kMaxElements) { |
10225 // This should be caught before we reach here. | 10238 // This should be caught before we reach here. |
10226 FATAL1("Fatal error in PcDescriptors::New: " | 10239 FATAL1("Fatal error in PcDescriptors::New: " |
10227 "invalid num_descriptors %" Pd "\n", num_descriptors); | 10240 "invalid num_descriptors %" Pd "\n", num_descriptors); |
10228 } | 10241 } |
10229 PcDescriptors& result = PcDescriptors::Handle(); | 10242 PcDescriptors& result = PcDescriptors::Handle(); |
10230 { | 10243 { |
10231 uword size = PcDescriptors::InstanceSize(num_descriptors); | 10244 uword size = PcDescriptors::InstanceSize(num_descriptors, |
| 10245 has_try_index ? RawPcDescriptors::kFullRecSize |
| 10246 : RawPcDescriptors::kCompressedRecSize); |
10232 RawObject* raw = Object::Allocate(PcDescriptors::kClassId, | 10247 RawObject* raw = Object::Allocate(PcDescriptors::kClassId, |
10233 size, | 10248 size, |
10234 Heap::kOld); | 10249 Heap::kOld); |
10235 NoGCScope no_gc; | 10250 NoGCScope no_gc; |
10236 result ^= raw; | 10251 result ^= raw; |
10237 result.SetLength(num_descriptors); | 10252 result.SetLength(num_descriptors); |
| 10253 if (has_try_index) { |
| 10254 result.SetRecordSizeInBytes(RawPcDescriptors::kFullRecSize); |
| 10255 } else { |
| 10256 result.SetRecordSizeInBytes(RawPcDescriptors::kCompressedRecSize); |
| 10257 } |
10238 } | 10258 } |
10239 return result.raw(); | 10259 return result.raw(); |
10240 } | 10260 } |
10241 | 10261 |
10242 | 10262 |
10243 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { | 10263 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { |
10244 switch (kind) { | 10264 switch (kind) { |
10245 case RawPcDescriptors::kDeopt: return "deopt "; | 10265 case RawPcDescriptors::kDeopt: return "deopt "; |
10246 case RawPcDescriptors::kIcCall: return "ic-call "; | 10266 case RawPcDescriptors::kIcCall: return "ic-call "; |
10247 case RawPcDescriptors::kOptStaticCall: return "opt-call "; | 10267 case RawPcDescriptors::kOptStaticCall: return "opt-call "; |
(...skipping 28 matching lines...) Expand all Loading... |
10276 // "*" in a printf format specifier tells it to read the field width from | 10296 // "*" in a printf format specifier tells it to read the field width from |
10277 // the printf argument list. | 10297 // the printf argument list. |
10278 const char* kFormat = | 10298 const char* kFormat = |
10279 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; | 10299 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; |
10280 // First compute the buffer size required. | 10300 // First compute the buffer size required. |
10281 intptr_t len = 1; // Trailing '\0'. | 10301 intptr_t len = 1; // Trailing '\0'. |
10282 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10302 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10283 while (iter.HasNext()) { | 10303 while (iter.HasNext()) { |
10284 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10304 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
10285 len += OS::SNPrint(NULL, 0, kFormat, addr_width, | 10305 len += OS::SNPrint(NULL, 0, kFormat, addr_width, |
10286 rec.pc, | 10306 rec.pc(), |
10287 KindAsStr(rec.kind()), | 10307 KindAsStr(rec.kind()), |
10288 rec.deopt_id, | 10308 rec.deopt_id(), |
10289 rec.token_pos, | 10309 rec.token_pos(), |
10290 rec.try_index); | 10310 rec.try_index()); |
10291 } | 10311 } |
10292 // Allocate the buffer. | 10312 // Allocate the buffer. |
10293 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); | 10313 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); |
10294 // Layout the fields in the buffer. | 10314 // Layout the fields in the buffer. |
10295 intptr_t index = 0; | 10315 intptr_t index = 0; |
10296 Iterator iter2(*this, RawPcDescriptors::kAnyKind); | 10316 Iterator iter2(*this, RawPcDescriptors::kAnyKind); |
10297 while (iter2.HasNext()) { | 10317 while (iter2.HasNext()) { |
10298 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next(); | 10318 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next(); |
10299 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, | 10319 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, |
10300 rec.pc, | 10320 rec.pc(), |
10301 KindAsStr(rec.kind()), | 10321 KindAsStr(rec.kind()), |
10302 rec.deopt_id, | 10322 rec.deopt_id(), |
10303 rec.token_pos, | 10323 rec.token_pos(), |
10304 rec.try_index); | 10324 rec.try_index()); |
10305 } | 10325 } |
10306 return buffer; | 10326 return buffer; |
10307 } | 10327 } |
10308 | 10328 |
10309 | 10329 |
10310 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { | 10330 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { |
10311 jsobj->AddProperty("type", JSONType(false)); | 10331 jsobj->AddProperty("type", JSONType(false)); |
10312 // TODO(johnmccutchan): Generate a valid ID. | 10332 // TODO(johnmccutchan): Generate a valid ID. |
10313 // PcDescriptors hang off a Code object but do not have a back reference to | 10333 // PcDescriptors hang off a Code object but do not have a back reference to |
10314 // generate an ID. Currently we only print PcDescriptors inline with a Code. | 10334 // generate an ID. Currently we only print PcDescriptors inline with a Code. |
10315 jsobj->AddProperty("id", ""); | 10335 jsobj->AddProperty("id", ""); |
10316 JSONArray members(jsobj, "members"); | 10336 JSONArray members(jsobj, "members"); |
10317 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10337 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10318 while (iter.HasNext()) { | 10338 while (iter.HasNext()) { |
10319 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10339 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
10320 JSONObject descriptor(&members); | 10340 JSONObject descriptor(&members); |
10321 descriptor.AddPropertyF("pc", "%" Px "", rec.pc); | 10341 descriptor.AddPropertyF("pc", "%" Px "", rec.pc()); |
10322 descriptor.AddProperty("kind", KindAsStr(rec.kind())); | 10342 descriptor.AddProperty("kind", KindAsStr(rec.kind())); |
10323 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id)); | 10343 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id())); |
10324 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos)); | 10344 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos())); |
10325 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index)); | 10345 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index())); |
10326 } | 10346 } |
10327 } | 10347 } |
10328 | 10348 |
10329 | 10349 |
10330 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { | 10350 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { |
10331 JSONObject jsobj(stream); | 10351 JSONObject jsobj(stream); |
10332 PrintToJSONObject(&jsobj); | 10352 PrintToJSONObject(&jsobj); |
10333 } | 10353 } |
10334 | 10354 |
10335 | 10355 |
(...skipping 16 matching lines...) Expand all Loading... |
10352 if (!function.IsOptimizable()) { | 10372 if (!function.IsOptimizable()) { |
10353 return; | 10373 return; |
10354 } | 10374 } |
10355 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); | 10375 Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); |
10356 while (iter.HasNext()) { | 10376 while (iter.HasNext()) { |
10357 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10377 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
10358 RawPcDescriptors::Kind kind = rec.kind(); | 10378 RawPcDescriptors::Kind kind = rec.kind(); |
10359 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. | 10379 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. |
10360 intptr_t deopt_id = Isolate::kNoDeoptId; | 10380 intptr_t deopt_id = Isolate::kNoDeoptId; |
10361 | 10381 |
10362 deopt_id = rec.deopt_id; | 10382 deopt_id = rec.deopt_id(); |
10363 if (Isolate::IsDeoptAfter(deopt_id)) { | 10383 if (Isolate::IsDeoptAfter(deopt_id)) { |
10364 // TODO(vegorov): some instructions contain multiple calls and have | 10384 // TODO(vegorov): some instructions contain multiple calls and have |
10365 // multiple "after" targets recorded. Right now it is benign but might | 10385 // multiple "after" targets recorded. Right now it is benign but might |
10366 // lead to issues in the future. Fix that and enable verification. | 10386 // lead to issues in the future. Fix that and enable verification. |
10367 continue; | 10387 continue; |
10368 } | 10388 } |
10369 | 10389 |
10370 Iterator nested(iter); | 10390 Iterator nested(iter); |
10371 while (nested.HasNext()) { | 10391 while (nested.HasNext()) { |
10372 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next(); | 10392 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next(); |
10373 if (kind == nested_rec.kind()) { | 10393 if (kind == nested_rec.kind()) { |
10374 if (deopt_id != Isolate::kNoDeoptId) { | 10394 if (deopt_id != Isolate::kNoDeoptId) { |
10375 ASSERT(nested_rec.deopt_id != deopt_id); | 10395 ASSERT(nested_rec.deopt_id() != deopt_id); |
10376 } | 10396 } |
10377 } | 10397 } |
10378 } | 10398 } |
10379 } | 10399 } |
10380 #endif // DEBUG | 10400 #endif // DEBUG |
10381 } | 10401 } |
10382 | 10402 |
10383 | 10403 |
10384 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { | 10404 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const { |
10385 Iterator iter(*this, RawPcDescriptors::kAnyKind); | 10405 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
10386 while (iter.HasNext()) { | 10406 while (iter.HasNext()) { |
10387 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 10407 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
10388 if (rec.kind() == kind) { | 10408 if (rec.kind() == kind) { |
10389 return rec.pc; | 10409 return rec.pc(); |
10390 } | 10410 } |
10391 } | 10411 } |
10392 return 0; | 10412 return 0; |
10393 } | 10413 } |
10394 | 10414 |
10395 | 10415 |
10396 bool Stackmap::GetBit(intptr_t bit_index) const { | 10416 bool Stackmap::GetBit(intptr_t bit_index) const { |
10397 ASSERT(InRange(bit_index)); | 10417 ASSERT(InRange(bit_index)); |
10398 int byte_index = bit_index >> kBitsPerByteLog2; | 10418 int byte_index = bit_index >> kBitsPerByteLog2; |
10399 int bit_remainder = bit_index & (kBitsPerByte - 1); | 10419 int bit_remainder = bit_index & (kBitsPerByte - 1); |
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11880 } | 11900 } |
11881 return Code::null(); | 11901 return Code::null(); |
11882 } | 11902 } |
11883 | 11903 |
11884 | 11904 |
11885 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 11905 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
11886 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11906 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11887 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 11907 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
11888 while (iter.HasNext()) { | 11908 while (iter.HasNext()) { |
11889 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11909 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
11890 if (rec.pc == pc) { | 11910 if (rec.pc() == pc) { |
11891 return rec.token_pos; | 11911 return rec.token_pos(); |
11892 } | 11912 } |
11893 } | 11913 } |
11894 return -1; | 11914 return -1; |
11895 } | 11915 } |
11896 | 11916 |
11897 | 11917 |
11898 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 11918 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
11899 RawPcDescriptors::Kind kind) const { | 11919 RawPcDescriptors::Kind kind) const { |
11900 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11920 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11901 PcDescriptors::Iterator iter(descriptors, kind); | 11921 PcDescriptors::Iterator iter(descriptors, kind); |
11902 while (iter.HasNext()) { | 11922 while (iter.HasNext()) { |
11903 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11923 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
11904 if (rec.deopt_id == deopt_id) { | 11924 if (rec.deopt_id() == deopt_id) { |
11905 uword pc = rec.pc; | 11925 uword pc = rec.pc(); |
11906 ASSERT(ContainsInstructionAt(pc)); | 11926 ASSERT(ContainsInstructionAt(pc)); |
11907 return pc; | 11927 return pc; |
11908 } | 11928 } |
11909 } | 11929 } |
11910 return 0; | 11930 return 0; |
11911 } | 11931 } |
11912 | 11932 |
11913 | 11933 |
11914 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 11934 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
11915 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 11935 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
11916 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 11936 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
11917 while (iter.HasNext()) { | 11937 while (iter.HasNext()) { |
11918 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); | 11938 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); |
11919 if (rec.pc == pc) { | 11939 if (rec.pc() == pc) { |
11920 return rec.deopt_id; | 11940 return rec.deopt_id(); |
11921 } | 11941 } |
11922 } | 11942 } |
11923 return Isolate::kNoDeoptId; | 11943 return Isolate::kNoDeoptId; |
11924 } | 11944 } |
11925 | 11945 |
11926 | 11946 |
11927 const char* Code::ToCString() const { | 11947 const char* Code::ToCString() const { |
11928 const char* kFormat = "Code entry:%p"; | 11948 const char* kFormat = "Code entry:%p"; |
11929 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; | 11949 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; |
11930 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 11950 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
(...skipping 7150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19081 return tag_label.ToCString(); | 19101 return tag_label.ToCString(); |
19082 } | 19102 } |
19083 | 19103 |
19084 | 19104 |
19085 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19105 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
19086 Instance::PrintJSONImpl(stream, ref); | 19106 Instance::PrintJSONImpl(stream, ref); |
19087 } | 19107 } |
19088 | 19108 |
19089 | 19109 |
19090 } // namespace dart | 19110 } // namespace dart |
OLD | NEW |