| 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 |