Chromium Code Reviews| 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 12252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12263 return *comments; | 12263 return *comments; |
| 12264 } | 12264 } |
| 12265 | 12265 |
| 12266 | 12266 |
| 12267 void Code::set_comments(const Code::Comments& comments) const { | 12267 void Code::set_comments(const Code::Comments& comments) const { |
| 12268 ASSERT(comments.comments_.IsOld()); | 12268 ASSERT(comments.comments_.IsOld()); |
| 12269 StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); | 12269 StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); |
| 12270 } | 12270 } |
| 12271 | 12271 |
| 12272 | 12272 |
| 12273 void Code::set_inlined_intervals(const Array& value) const { | 12273 void Code::SetPrologueOffset(intptr_t offset) const { |
| 12274 ASSERT(value.IsOld()); | 12274 ASSERT(offset >= 0); |
| 12275 StorePointer(&raw_ptr()->inlined_intervals_, value.raw()); | 12275 StoreSmi( |
| 12276 reinterpret_cast<RawSmi* const *>(&raw_ptr()->return_address_metadata_), | |
| 12277 Smi::New(offset)); | |
| 12276 } | 12278 } |
| 12277 | 12279 |
| 12278 | 12280 |
| 12279 void Code::set_inlined_id_to_function(const Array& value) const { | 12281 intptr_t Code::GetPrologueOffset() const { |
| 12280 ASSERT(value.IsOld()); | 12282 const Object& object = Object::Handle(raw_ptr()->return_address_metadata_); |
| 12281 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); | 12283 if (object.IsNull() || !object.IsSmi()) { |
|
srdjan
2015/05/21 16:06:33
How can it be non-null and non-Smi? (Add comment i
Cutch
2015/05/22 01:11:14
I've added a comment. In the future we may overloa
| |
| 12284 return -1; | |
| 12285 } | |
| 12286 return Smi::Cast(object).Value(); | |
| 12282 } | 12287 } |
| 12283 | 12288 |
| 12284 | 12289 |
| 12290 RawArray* Code::GetInlinedIntervals() const { | |
| 12291 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_); | |
| 12292 if (metadata.IsNull()) { | |
| 12293 return metadata.raw(); | |
| 12294 } | |
| 12295 return reinterpret_cast<RawArray*>( | |
| 12296 metadata.At(RawCode::kInlinedIntervalsIndex)); | |
| 12297 } | |
| 12298 | |
| 12299 | |
| 12300 void Code::SetInlinedIntervals(const Array& value) const { | |
| 12301 if (raw_ptr()->inlined_metadata_ == Array::null()) { | |
| 12302 StorePointer(&raw_ptr()->inlined_metadata_, | |
| 12303 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld)); | |
| 12304 } | |
| 12305 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_); | |
| 12306 ASSERT(!metadata.IsNull()); | |
| 12307 ASSERT(metadata.IsOld()); | |
| 12308 ASSERT(value.IsOld()); | |
| 12309 metadata.SetAt(RawCode::kInlinedIntervalsIndex, value); | |
| 12310 } | |
| 12311 | |
| 12312 | |
| 12313 RawArray* Code::GetInlinedIdToFunction() const { | |
| 12314 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_); | |
| 12315 if (metadata.IsNull()) { | |
| 12316 return metadata.raw(); | |
| 12317 } | |
| 12318 return reinterpret_cast<RawArray*>( | |
| 12319 metadata.At(RawCode::kInlinedIdToFunctionIndex)); | |
| 12320 } | |
| 12321 | |
| 12322 | |
| 12323 void Code::SetInlinedIdToFunction(const Array& value) const { | |
| 12324 if (raw_ptr()->inlined_metadata_ == Array::null()) { | |
| 12325 StorePointer(&raw_ptr()->inlined_metadata_, | |
| 12326 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld)); | |
| 12327 } | |
| 12328 const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_); | |
| 12329 ASSERT(!metadata.IsNull()); | |
| 12330 ASSERT(metadata.IsOld()); | |
| 12331 ASSERT(value.IsOld()); | |
| 12332 ASSERT(value.IsOld()); | |
|
srdjan
2015/05/21 16:06:34
ONe too many check for value.IsOld()
Cutch
2015/05/22 01:11:14
Done.
| |
| 12333 metadata.SetAt(RawCode::kInlinedIdToFunctionIndex, value); | |
| 12334 } | |
| 12335 | |
| 12336 | |
| 12285 RawCode* Code::New(intptr_t pointer_offsets_length) { | 12337 RawCode* Code::New(intptr_t pointer_offsets_length) { |
| 12286 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { | 12338 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { |
| 12287 // This should be caught before we reach here. | 12339 // This should be caught before we reach here. |
| 12288 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", | 12340 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", |
| 12289 pointer_offsets_length); | 12341 pointer_offsets_length); |
| 12290 } | 12342 } |
| 12291 ASSERT(Object::code_class() != Class::null()); | 12343 ASSERT(Object::code_class() != Class::null()); |
| 12292 Code& result = Code::Handle(); | 12344 Code& result = Code::Handle(); |
| 12293 { | 12345 { |
| 12294 uword size = Code::InstanceSize(pointer_offsets_length); | 12346 uword size = Code::InstanceSize(pointer_offsets_length); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12377 if (FLAG_write_protect_code) { | 12429 if (FLAG_write_protect_code) { |
| 12378 uword address = RawObject::ToAddr(instrs.raw()); | 12430 uword address = RawObject::ToAddr(instrs.raw()); |
| 12379 bool status = VirtualMemory::Protect( | 12431 bool status = VirtualMemory::Protect( |
| 12380 reinterpret_cast<void*>(address), | 12432 reinterpret_cast<void*>(address), |
| 12381 instrs.raw()->Size(), | 12433 instrs.raw()->Size(), |
| 12382 VirtualMemory::kReadExecute); | 12434 VirtualMemory::kReadExecute); |
| 12383 ASSERT(status); | 12435 ASSERT(status); |
| 12384 } | 12436 } |
| 12385 } | 12437 } |
| 12386 code.set_comments(assembler->GetCodeComments()); | 12438 code.set_comments(assembler->GetCodeComments()); |
| 12439 if (assembler->prologue_offset() >= 0) { | |
| 12440 code.SetPrologueOffset(assembler->prologue_offset()); | |
| 12441 } | |
| 12387 INC_STAT(Isolate::Current(), | 12442 INC_STAT(Isolate::Current(), |
| 12388 total_code_size, code.comments().comments_.Length()); | 12443 total_code_size, code.comments().comments_.Length()); |
| 12389 return code.raw(); | 12444 return code.raw(); |
| 12390 } | 12445 } |
| 12391 | 12446 |
| 12392 | 12447 |
| 12393 RawCode* Code::FinalizeCode(const Function& function, | 12448 RawCode* Code::FinalizeCode(const Function& function, |
| 12394 Assembler* assembler, | 12449 Assembler* assembler, |
| 12395 bool optimized) { | 12450 bool optimized) { |
| 12396 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 12451 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12608 // Only disassemble alive code objects. | 12663 // Only disassemble alive code objects. |
| 12609 DisassembleToJSONStream formatter(jsarr); | 12664 DisassembleToJSONStream formatter(jsarr); |
| 12610 Disassemble(&formatter); | 12665 Disassemble(&formatter); |
| 12611 } | 12666 } |
| 12612 } | 12667 } |
| 12613 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 12668 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 12614 if (!descriptors.IsNull()) { | 12669 if (!descriptors.IsNull()) { |
| 12615 JSONObject desc(&jsobj, "_descriptors"); | 12670 JSONObject desc(&jsobj, "_descriptors"); |
| 12616 descriptors.PrintToJSONObject(&desc, false); | 12671 descriptors.PrintToJSONObject(&desc, false); |
| 12617 } | 12672 } |
| 12618 const Array& inlined_function_table = Array::Handle(inlined_id_to_function()); | 12673 const Array& inlined_function_table = Array::Handle(GetInlinedIdToFunction()); |
| 12619 if (!inlined_function_table.IsNull() && | 12674 if (!inlined_function_table.IsNull() && |
| 12620 (inlined_function_table.Length() > 0)) { | 12675 (inlined_function_table.Length() > 0)) { |
| 12621 JSONArray inlined_functions(&jsobj, "_inlinedFunctions"); | 12676 JSONArray inlined_functions(&jsobj, "_inlinedFunctions"); |
| 12622 Function& function = Function::Handle(); | 12677 Function& function = Function::Handle(); |
| 12623 for (intptr_t i = 0; i < inlined_function_table.Length(); i++) { | 12678 for (intptr_t i = 0; i < inlined_function_table.Length(); i++) { |
| 12624 function ^= inlined_function_table.At(i); | 12679 function ^= inlined_function_table.At(i); |
| 12625 ASSERT(!function.IsNull()); | 12680 ASSERT(!function.IsNull()); |
| 12626 inlined_functions.AddValue(function); | 12681 inlined_functions.AddValue(function); |
| 12627 } | 12682 } |
| 12628 } | 12683 } |
| 12629 const Array& intervals = Array::Handle(inlined_intervals()); | 12684 const Array& intervals = Array::Handle(GetInlinedIntervals()); |
| 12630 if (!intervals.IsNull() && (intervals.Length() > 0)) { | 12685 if (!intervals.IsNull() && (intervals.Length() > 0)) { |
| 12631 Smi& start = Smi::Handle(); | 12686 Smi& start = Smi::Handle(); |
| 12632 Smi& end = Smi::Handle(); | 12687 Smi& end = Smi::Handle(); |
| 12633 Smi& temp_smi = Smi::Handle(); | 12688 Smi& temp_smi = Smi::Handle(); |
| 12634 JSONArray inline_intervals(&jsobj, "_inlinedIntervals"); | 12689 JSONArray inline_intervals(&jsobj, "_inlinedIntervals"); |
| 12635 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; | 12690 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; |
| 12636 i += Code::kInlIntNumEntries) { | 12691 i += Code::kInlIntNumEntries) { |
| 12637 start ^= intervals.At(i + Code::kInlIntStart); | 12692 start ^= intervals.At(i + Code::kInlIntStart); |
| 12638 if (start.IsNull()) { | 12693 if (start.IsNull()) { |
| 12639 continue; | 12694 continue; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12699 return map->raw(); // We found a stack map for this frame. | 12754 return map->raw(); // We found a stack map for this frame. |
| 12700 } | 12755 } |
| 12701 } | 12756 } |
| 12702 ASSERT(!is_optimized()); | 12757 ASSERT(!is_optimized()); |
| 12703 return Stackmap::null(); | 12758 return Stackmap::null(); |
| 12704 } | 12759 } |
| 12705 | 12760 |
| 12706 | 12761 |
| 12707 intptr_t Code::GetCallerId(intptr_t inlined_id) const { | 12762 intptr_t Code::GetCallerId(intptr_t inlined_id) const { |
| 12708 if (inlined_id < 0) return -1; | 12763 if (inlined_id < 0) return -1; |
| 12709 const Array& intervals = Array::Handle(inlined_intervals()); | 12764 const Array& intervals = Array::Handle(GetInlinedIntervals()); |
| 12710 if (intervals.IsNull() || (intervals.Length() == 0)) return -1; | 12765 if (intervals.IsNull() || (intervals.Length() == 0)) return -1; |
| 12711 Smi& temp_smi = Smi::Handle(); | 12766 Smi& temp_smi = Smi::Handle(); |
| 12712 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; | 12767 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; |
| 12713 i += Code::kInlIntNumEntries) { | 12768 i += Code::kInlIntNumEntries) { |
| 12714 temp_smi ^= intervals.At(i + Code::kInlIntInliningId); | 12769 temp_smi ^= intervals.At(i + Code::kInlIntInliningId); |
| 12715 if (temp_smi.Value() == inlined_id) { | 12770 if (temp_smi.Value() == inlined_id) { |
| 12716 temp_smi ^= intervals.At(i + Code::kInlIntCallerId); | 12771 temp_smi ^= intervals.At(i + Code::kInlIntCallerId); |
| 12717 return temp_smi.Value(); | 12772 return temp_smi.Value(); |
| 12718 } | 12773 } |
| 12719 } | 12774 } |
| 12720 return -1; | 12775 return -1; |
| 12721 } | 12776 } |
| 12722 | 12777 |
| 12723 | 12778 |
| 12724 void Code::GetInlinedFunctionsAt( | 12779 void Code::GetInlinedFunctionsAt( |
| 12725 intptr_t offset, GrowableArray<Function*>* fs) const { | 12780 intptr_t offset, GrowableArray<Function*>* fs) const { |
| 12726 fs->Clear(); | 12781 fs->Clear(); |
| 12727 const Array& intervals = Array::Handle(inlined_intervals()); | 12782 const Array& intervals = Array::Handle(GetInlinedIntervals()); |
| 12728 if (intervals.IsNull() || (intervals.Length() == 0)) { | 12783 if (intervals.IsNull() || (intervals.Length() == 0)) { |
| 12729 // E.g., for code stubs. | 12784 // E.g., for code stubs. |
| 12730 return; | 12785 return; |
| 12731 } | 12786 } |
| 12732 // First find the right interval. TODO(srdjan): use binary search since | 12787 // First find the right interval. TODO(srdjan): use binary search since |
| 12733 // intervals are sorted. | 12788 // intervals are sorted. |
| 12734 Smi& start = Smi::Handle(); | 12789 Smi& start = Smi::Handle(); |
| 12735 Smi& end = Smi::Handle(); | 12790 Smi& end = Smi::Handle(); |
| 12736 intptr_t found_interval_ix = intervals.Length() - Code::kInlIntNumEntries; | 12791 intptr_t found_interval_ix = intervals.Length() - Code::kInlIntNumEntries; |
| 12737 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; | 12792 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; |
| 12738 i += Code::kInlIntNumEntries) { | 12793 i += Code::kInlIntNumEntries) { |
| 12739 start ^= intervals.At(i + Code::kInlIntStart); | 12794 start ^= intervals.At(i + Code::kInlIntStart); |
| 12740 if (!start.IsNull()) { | 12795 if (!start.IsNull()) { |
| 12741 end ^= intervals.At(i + Code::kInlIntNumEntries + Code::kInlIntStart); | 12796 end ^= intervals.At(i + Code::kInlIntNumEntries + Code::kInlIntStart); |
| 12742 if ((start.Value() <= offset) && (offset < end.Value())) { | 12797 if ((start.Value() <= offset) && (offset < end.Value())) { |
| 12743 found_interval_ix = i; | 12798 found_interval_ix = i; |
| 12744 break; | 12799 break; |
| 12745 } | 12800 } |
| 12746 } | 12801 } |
| 12747 } | 12802 } |
| 12748 | 12803 |
| 12749 // Find all functions. | 12804 // Find all functions. |
| 12750 const Array& id_map = Array::Handle(inlined_id_to_function()); | 12805 const Array& id_map = Array::Handle(GetInlinedIdToFunction()); |
| 12751 Smi& temp_smi = Smi::Handle(); | 12806 Smi& temp_smi = Smi::Handle(); |
| 12752 temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntInliningId); | 12807 temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntInliningId); |
| 12753 intptr_t inlining_id = temp_smi.Value(); | 12808 intptr_t inlining_id = temp_smi.Value(); |
| 12754 ASSERT(inlining_id >= 0); | 12809 ASSERT(inlining_id >= 0); |
| 12755 temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntCallerId); | 12810 temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntCallerId); |
| 12756 intptr_t caller_id = temp_smi.Value(); | 12811 intptr_t caller_id = temp_smi.Value(); |
| 12757 while (inlining_id >= 0) { | 12812 while (inlining_id >= 0) { |
| 12758 Function& function = Function::ZoneHandle(); | 12813 Function& function = Function::ZoneHandle(); |
| 12759 function ^= id_map.At(inlining_id); | 12814 function ^= id_map.At(inlining_id); |
| 12760 fs->Add(&function); | 12815 fs->Add(&function); |
| 12761 inlining_id = caller_id; | 12816 inlining_id = caller_id; |
| 12762 caller_id = GetCallerId(inlining_id); | 12817 caller_id = GetCallerId(inlining_id); |
| 12763 } | 12818 } |
| 12764 } | 12819 } |
| 12765 | 12820 |
| 12766 | 12821 |
| 12767 void Code::DumpInlinedIntervals() const { | 12822 void Code::DumpInlinedIntervals() const { |
| 12768 OS::Print("Inlined intervals:\n"); | 12823 OS::Print("Inlined intervals:\n"); |
| 12769 const Array& intervals = Array::Handle(inlined_intervals()); | 12824 const Array& intervals = Array::Handle(GetInlinedIntervals()); |
| 12770 if (intervals.IsNull() || (intervals.Length() == 0)) return; | 12825 if (intervals.IsNull() || (intervals.Length() == 0)) return; |
| 12771 Smi& start = Smi::Handle(); | 12826 Smi& start = Smi::Handle(); |
| 12772 Smi& inlining_id = Smi::Handle(); | 12827 Smi& inlining_id = Smi::Handle(); |
| 12773 Smi& caller_id = Smi::Handle(); | 12828 Smi& caller_id = Smi::Handle(); |
| 12774 for (intptr_t i = 0; i < intervals.Length(); i += Code::kInlIntNumEntries) { | 12829 for (intptr_t i = 0; i < intervals.Length(); i += Code::kInlIntNumEntries) { |
| 12775 start ^= intervals.At(i + Code::kInlIntStart); | 12830 start ^= intervals.At(i + Code::kInlIntStart); |
| 12776 ASSERT(!start.IsNull()); | 12831 ASSERT(!start.IsNull()); |
| 12777 if (start.IsNull()) continue; | 12832 if (start.IsNull()) continue; |
| 12778 inlining_id ^= intervals.At(i + Code::kInlIntInliningId); | 12833 inlining_id ^= intervals.At(i + Code::kInlIntInliningId); |
| 12779 caller_id ^= intervals.At(i + Code::kInlIntCallerId); | 12834 caller_id ^= intervals.At(i + Code::kInlIntCallerId); |
| 12780 OS::Print(" %" Px " id: %" Pd " caller-id: %" Pd " \n", | 12835 OS::Print(" %" Px " id: %" Pd " caller-id: %" Pd " \n", |
| 12781 start.Value(), inlining_id.Value(), caller_id.Value()); | 12836 start.Value(), inlining_id.Value(), caller_id.Value()); |
| 12782 } | 12837 } |
| 12783 OS::Print("Inlined ids:\n"); | 12838 OS::Print("Inlined ids:\n"); |
| 12784 const Array& id_map = Array::Handle(inlined_id_to_function()); | 12839 const Array& id_map = Array::Handle(GetInlinedIdToFunction()); |
| 12785 Function& function = Function::Handle(); | 12840 Function& function = Function::Handle(); |
| 12786 for (intptr_t i = 0; i < id_map.Length(); i++) { | 12841 for (intptr_t i = 0; i < id_map.Length(); i++) { |
| 12787 function ^= id_map.At(i); | 12842 function ^= id_map.At(i); |
| 12788 if (!function.IsNull()) { | 12843 if (!function.IsNull()) { |
| 12789 OS::Print(" %" Pd ": %s\n", i, function.ToQualifiedCString()); | 12844 OS::Print(" %" Pd ": %s\n", i, function.ToQualifiedCString()); |
| 12790 } | 12845 } |
| 12791 } | 12846 } |
| 12792 } | 12847 } |
| 12793 | 12848 |
| 12794 | 12849 |
| (...skipping 7935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20730 return tag_label.ToCString(); | 20785 return tag_label.ToCString(); |
| 20731 } | 20786 } |
| 20732 | 20787 |
| 20733 | 20788 |
| 20734 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 20789 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 20735 Instance::PrintJSONImpl(stream, ref); | 20790 Instance::PrintJSONImpl(stream, ref); |
| 20736 } | 20791 } |
| 20737 | 20792 |
| 20738 | 20793 |
| 20739 } // namespace dart | 20794 } // namespace dart |
| OLD | NEW |