| 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/become.h" | 10 #include "vm/become.h" |
| (...skipping 5247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5258 | 5258 |
| 5259 | 5259 |
| 5260 void Function::SetInstructions(const Code& value) const { | 5260 void Function::SetInstructions(const Code& value) const { |
| 5261 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 5261 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
| 5262 SetInstructionsSafe(value); | 5262 SetInstructionsSafe(value); |
| 5263 } | 5263 } |
| 5264 | 5264 |
| 5265 | 5265 |
| 5266 void Function::SetInstructionsSafe(const Code& value) const { | 5266 void Function::SetInstructionsSafe(const Code& value) const { |
| 5267 StorePointer(&raw_ptr()->code_, value.raw()); | 5267 StorePointer(&raw_ptr()->code_, value.raw()); |
| 5268 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); | 5268 StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint()); |
| 5269 } | 5269 } |
| 5270 | 5270 |
| 5271 | 5271 |
| 5272 void Function::AttachCode(const Code& value) const { | 5272 void Function::AttachCode(const Code& value) const { |
| 5273 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 5273 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
| 5274 // Finish setting up code before activating it. | 5274 // Finish setting up code before activating it. |
| 5275 value.set_owner(*this); | 5275 value.set_owner(*this); |
| 5276 SetInstructions(value); | 5276 SetInstructions(value); |
| 5277 ASSERT(Function::Handle(value.function()).IsNull() || | 5277 ASSERT(Function::Handle(value.function()).IsNull() || |
| 5278 (value.function() == this->raw())); | 5278 (value.function() == this->raw())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5309 ASSERT(HasOptimizedCode()); | 5309 ASSERT(HasOptimizedCode()); |
| 5310 Thread* thread = Thread::Current(); | 5310 Thread* thread = Thread::Current(); |
| 5311 Isolate* isolate = thread->isolate(); | 5311 Isolate* isolate = thread->isolate(); |
| 5312 Zone* zone = thread->zone(); | 5312 Zone* zone = thread->zone(); |
| 5313 ASSERT(thread->IsMutatorThread()); | 5313 ASSERT(thread->IsMutatorThread()); |
| 5314 const Code& current_code = Code::Handle(zone, CurrentCode()); | 5314 const Code& current_code = Code::Handle(zone, CurrentCode()); |
| 5315 | 5315 |
| 5316 if (FLAG_trace_deoptimization_verbose) { | 5316 if (FLAG_trace_deoptimization_verbose) { |
| 5317 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", | 5317 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", |
| 5318 ToFullyQualifiedCString(), | 5318 ToFullyQualifiedCString(), |
| 5319 current_code.EntryPoint()); | 5319 current_code.UncheckedEntryPoint()); |
| 5320 } | 5320 } |
| 5321 current_code.DisableDartCode(); | 5321 current_code.DisableDartCode(); |
| 5322 const Error& error = Error::Handle(zone, | 5322 const Error& error = Error::Handle(zone, |
| 5323 Compiler::EnsureUnoptimizedCode(thread, *this)); | 5323 Compiler::EnsureUnoptimizedCode(thread, *this)); |
| 5324 if (!error.IsNull()) { | 5324 if (!error.IsNull()) { |
| 5325 Exceptions::PropagateError(error); | 5325 Exceptions::PropagateError(error); |
| 5326 } | 5326 } |
| 5327 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); | 5327 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); |
| 5328 AttachCode(unopt_code); | 5328 AttachCode(unopt_code); |
| 5329 unopt_code.Enable(); | 5329 unopt_code.Enable(); |
| (...skipping 7669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12999 } | 12999 } |
| 13000 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); | 13000 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); |
| 13001 if (Isolate::Current()->compilation_allowed()) { | 13001 if (Isolate::Current()->compilation_allowed()) { |
| 13002 data.SetAt(data_pos + 1, target); | 13002 data.SetAt(data_pos + 1, target); |
| 13003 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); | 13003 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); |
| 13004 } else { | 13004 } else { |
| 13005 // Precompilation only, after all functions have been compiled. | 13005 // Precompilation only, after all functions have been compiled. |
| 13006 ASSERT(target.HasCode()); | 13006 ASSERT(target.HasCode()); |
| 13007 const Code& code = Code::Handle(target.CurrentCode()); | 13007 const Code& code = Code::Handle(target.CurrentCode()); |
| 13008 const Smi& entry_point = | 13008 const Smi& entry_point = |
| 13009 Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint())); | 13009 Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint())); |
| 13010 data.SetAt(data_pos + 1, code); | 13010 data.SetAt(data_pos + 1, code); |
| 13011 data.SetAt(data_pos + 2, entry_point); | 13011 data.SetAt(data_pos + 2, entry_point); |
| 13012 } | 13012 } |
| 13013 // Multithreaded access to ICData requires setting of array to be the last | 13013 // Multithreaded access to ICData requires setting of array to be the last |
| 13014 // operation. | 13014 // operation. |
| 13015 set_ic_data_array(data); | 13015 set_ic_data_array(data); |
| 13016 } | 13016 } |
| 13017 | 13017 |
| 13018 | 13018 |
| 13019 void ICData::GetCheckAt(intptr_t index, | 13019 void ICData::GetCheckAt(intptr_t index, |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13669 } | 13669 } |
| 13670 return map.TokenPositionForPCOffset(offset); | 13670 return map.TokenPositionForPCOffset(offset); |
| 13671 } | 13671 } |
| 13672 | 13672 |
| 13673 | 13673 |
| 13674 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, | 13674 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, |
| 13675 ICData::DeoptReasonId* deopt_reason, | 13675 ICData::DeoptReasonId* deopt_reason, |
| 13676 uint32_t* deopt_flags) const { | 13676 uint32_t* deopt_flags) const { |
| 13677 ASSERT(is_optimized()); | 13677 ASSERT(is_optimized()); |
| 13678 const Instructions& instrs = Instructions::Handle(instructions()); | 13678 const Instructions& instrs = Instructions::Handle(instructions()); |
| 13679 uword code_entry = instrs.EntryPoint(); | 13679 uword code_entry = instrs.PayloadStart(); |
| 13680 const Array& table = Array::Handle(deopt_info_array()); | 13680 const Array& table = Array::Handle(deopt_info_array()); |
| 13681 if (table.IsNull()) { | 13681 if (table.IsNull()) { |
| 13682 ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT); | 13682 ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT); |
| 13683 return TypedData::null(); | 13683 return TypedData::null(); |
| 13684 } | 13684 } |
| 13685 // Linear search for the PC offset matching the target PC. | 13685 // Linear search for the PC offset matching the target PC. |
| 13686 intptr_t length = DeoptTable::GetLength(table); | 13686 intptr_t length = DeoptTable::GetLength(table); |
| 13687 Smi& offset = Smi::Handle(); | 13687 Smi& offset = Smi::Handle(); |
| 13688 Smi& reason_and_flags = Smi::Handle(); | 13688 Smi& reason_and_flags = Smi::Handle(); |
| 13689 TypedData& info = TypedData::Handle(); | 13689 TypedData& info = TypedData::Handle(); |
| 13690 for (intptr_t i = 0; i < length; ++i) { | 13690 for (intptr_t i = 0; i < length; ++i) { |
| 13691 DeoptTable::GetEntry(table, i, &offset, &info, &reason_and_flags); | 13691 DeoptTable::GetEntry(table, i, &offset, &info, &reason_and_flags); |
| 13692 if (pc == (code_entry + offset.Value())) { | 13692 if (pc == (code_entry + offset.Value())) { |
| 13693 ASSERT(!info.IsNull()); | 13693 ASSERT(!info.IsNull()); |
| 13694 *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 13694 *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
| 13695 *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); | 13695 *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); |
| 13696 return info.raw(); | 13696 return info.raw(); |
| 13697 } | 13697 } |
| 13698 } | 13698 } |
| 13699 *deopt_reason = ICData::kDeoptUnknown; | 13699 *deopt_reason = ICData::kDeoptUnknown; |
| 13700 return TypedData::null(); | 13700 return TypedData::null(); |
| 13701 } | 13701 } |
| 13702 | 13702 |
| 13703 | 13703 |
| 13704 intptr_t Code::BinarySearchInSCallTable(uword pc) const { | 13704 intptr_t Code::BinarySearchInSCallTable(uword pc) const { |
| 13705 NoSafepointScope no_safepoint; | 13705 NoSafepointScope no_safepoint; |
| 13706 const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); | 13706 const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); |
| 13707 RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - EntryPoint())); | 13707 RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart())); |
| 13708 intptr_t imin = 0; | 13708 intptr_t imin = 0; |
| 13709 intptr_t imax = table.Length() / kSCallTableEntryLength; | 13709 intptr_t imax = table.Length() / kSCallTableEntryLength; |
| 13710 while (imax >= imin) { | 13710 while (imax >= imin) { |
| 13711 const intptr_t imid = ((imax - imin) / 2) + imin; | 13711 const intptr_t imid = ((imax - imin) / 2) + imin; |
| 13712 const intptr_t real_index = imid * kSCallTableEntryLength; | 13712 const intptr_t real_index = imid * kSCallTableEntryLength; |
| 13713 RawObject* key_in_table = table.At(real_index); | 13713 RawObject* key_in_table = table.At(real_index); |
| 13714 if (key_in_table < key) { | 13714 if (key_in_table < key) { |
| 13715 imin = imid + 1; | 13715 imin = imid + 1; |
| 13716 } else if (key_in_table > key) { | 13716 } else if (key_in_table > key) { |
| 13717 imax = imid - 1; | 13717 imax = imid - 1; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13776 array.SetAt(i + kSCallTableCodeEntry, code); | 13776 array.SetAt(i + kSCallTableCodeEntry, code); |
| 13777 } | 13777 } |
| 13778 | 13778 |
| 13779 | 13779 |
| 13780 void Code::Disassemble(DisassemblyFormatter* formatter) const { | 13780 void Code::Disassemble(DisassemblyFormatter* formatter) const { |
| 13781 #ifndef PRODUCT | 13781 #ifndef PRODUCT |
| 13782 if (!FLAG_support_disassembler) { | 13782 if (!FLAG_support_disassembler) { |
| 13783 return; | 13783 return; |
| 13784 } | 13784 } |
| 13785 const Instructions& instr = Instructions::Handle(instructions()); | 13785 const Instructions& instr = Instructions::Handle(instructions()); |
| 13786 uword start = instr.EntryPoint(); | 13786 uword start = instr.PayloadStart(); |
| 13787 if (formatter == NULL) { | 13787 if (formatter == NULL) { |
| 13788 Disassembler::Disassemble(start, start + instr.size(), *this); | 13788 Disassembler::Disassemble(start, start + instr.size(), *this); |
| 13789 } else { | 13789 } else { |
| 13790 Disassembler::Disassemble(start, start + instr.size(), formatter, *this); | 13790 Disassembler::Disassemble(start, start + instr.size(), formatter, *this); |
| 13791 } | 13791 } |
| 13792 #endif | 13792 #endif |
| 13793 } | 13793 } |
| 13794 | 13794 |
| 13795 | 13795 |
| 13796 const Code::Comments& Code::comments() const { | 13796 const Code::Comments& Code::comments() const { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13961 #ifdef TARGET_ARCH_IA32 | 13961 #ifdef TARGET_ARCH_IA32 |
| 13962 assembler->set_code_object(code); | 13962 assembler->set_code_object(code); |
| 13963 #endif | 13963 #endif |
| 13964 Instructions& instrs = | 13964 Instructions& instrs = |
| 13965 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 13965 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
| 13966 INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize()); | 13966 INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize()); |
| 13967 INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize()); | 13967 INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize()); |
| 13968 | 13968 |
| 13969 // Copy the instructions into the instruction area and apply all fixups. | 13969 // Copy the instructions into the instruction area and apply all fixups. |
| 13970 // Embedded pointers are still in handles at this point. | 13970 // Embedded pointers are still in handles at this point. |
| 13971 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), | 13971 MemoryRegion region(reinterpret_cast<void*>(instrs.PayloadStart()), |
| 13972 instrs.size()); | 13972 instrs.size()); |
| 13973 assembler->FinalizeInstructions(region); | 13973 assembler->FinalizeInstructions(region); |
| 13974 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); | 13974 CPU::FlushICache(instrs.PayloadStart(), instrs.size()); |
| 13975 | 13975 |
| 13976 code.set_compile_timestamp(OS::GetCurrentMonotonicMicros()); | 13976 code.set_compile_timestamp(OS::GetCurrentMonotonicMicros()); |
| 13977 #ifndef PRODUCT | 13977 #ifndef PRODUCT |
| 13978 CodeObservers::NotifyAll(name, | 13978 CodeObservers::NotifyAll(name, |
| 13979 instrs.EntryPoint(), | 13979 instrs.PayloadStart(), |
| 13980 assembler->prologue_offset(), | 13980 assembler->prologue_offset(), |
| 13981 instrs.size(), | 13981 instrs.size(), |
| 13982 optimized); | 13982 optimized); |
| 13983 #endif | 13983 #endif |
| 13984 { | 13984 { |
| 13985 NoSafepointScope no_safepoint; | 13985 NoSafepointScope no_safepoint; |
| 13986 const ZoneGrowableArray<intptr_t>& pointer_offsets = | 13986 const ZoneGrowableArray<intptr_t>& pointer_offsets = |
| 13987 assembler->GetPointerOffsets(); | 13987 assembler->GetPointerOffsets(); |
| 13988 ASSERT(pointer_offsets.length() == pointer_offset_count); | 13988 ASSERT(pointer_offsets.length() == pointer_offset_count); |
| 13989 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); | 13989 ASSERT(code.pointer_offsets_length() == pointer_offsets.length()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14075 | 14075 |
| 14076 RawCode* Code::LookupCodeInVmIsolate(uword pc) { | 14076 RawCode* Code::LookupCodeInVmIsolate(uword pc) { |
| 14077 return LookupCodeInIsolate(Dart::vm_isolate(), pc); | 14077 return LookupCodeInIsolate(Dart::vm_isolate(), pc); |
| 14078 } | 14078 } |
| 14079 | 14079 |
| 14080 | 14080 |
| 14081 // Given a pc and a timestamp, lookup the code. | 14081 // Given a pc and a timestamp, lookup the code. |
| 14082 RawCode* Code::FindCode(uword pc, int64_t timestamp) { | 14082 RawCode* Code::FindCode(uword pc, int64_t timestamp) { |
| 14083 Code& code = Code::Handle(Code::LookupCode(pc)); | 14083 Code& code = Code::Handle(Code::LookupCode(pc)); |
| 14084 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 14084 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |
| 14085 (code.EntryPoint() == pc)) { | 14085 (code.PayloadStart() == pc)) { |
| 14086 // Found code in isolate. | 14086 // Found code in isolate. |
| 14087 return code.raw(); | 14087 return code.raw(); |
| 14088 } | 14088 } |
| 14089 code ^= Code::LookupCodeInVmIsolate(pc); | 14089 code ^= Code::LookupCodeInVmIsolate(pc); |
| 14090 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 14090 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |
| 14091 (code.EntryPoint() == pc)) { | 14091 (code.PayloadStart() == pc)) { |
| 14092 // Found code in VM isolate. | 14092 // Found code in VM isolate. |
| 14093 return code.raw(); | 14093 return code.raw(); |
| 14094 } | 14094 } |
| 14095 return Code::null(); | 14095 return Code::null(); |
| 14096 } | 14096 } |
| 14097 | 14097 |
| 14098 | 14098 |
| 14099 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { | 14099 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { |
| 14100 uword pc_offset = pc - EntryPoint(); | 14100 uword pc_offset = pc - PayloadStart(); |
| 14101 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 14101 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 14102 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 14102 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
| 14103 while (iter.MoveNext()) { | 14103 while (iter.MoveNext()) { |
| 14104 if (iter.PcOffset() == pc_offset) { | 14104 if (iter.PcOffset() == pc_offset) { |
| 14105 return iter.TokenPos(); | 14105 return iter.TokenPos(); |
| 14106 } | 14106 } |
| 14107 } | 14107 } |
| 14108 return TokenPosition::kNoSource; | 14108 return TokenPosition::kNoSource; |
| 14109 } | 14109 } |
| 14110 | 14110 |
| 14111 | 14111 |
| 14112 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 14112 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
| 14113 RawPcDescriptors::Kind kind) const { | 14113 RawPcDescriptors::Kind kind) const { |
| 14114 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 14114 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 14115 PcDescriptors::Iterator iter(descriptors, kind); | 14115 PcDescriptors::Iterator iter(descriptors, kind); |
| 14116 while (iter.MoveNext()) { | 14116 while (iter.MoveNext()) { |
| 14117 if (iter.DeoptId() == deopt_id) { | 14117 if (iter.DeoptId() == deopt_id) { |
| 14118 uword pc_offset = iter.PcOffset(); | 14118 uword pc_offset = iter.PcOffset(); |
| 14119 uword pc = EntryPoint() + pc_offset; | 14119 uword pc = PayloadStart() + pc_offset; |
| 14120 ASSERT(ContainsInstructionAt(pc)); | 14120 ASSERT(ContainsInstructionAt(pc)); |
| 14121 return pc; | 14121 return pc; |
| 14122 } | 14122 } |
| 14123 } | 14123 } |
| 14124 return 0; | 14124 return 0; |
| 14125 } | 14125 } |
| 14126 | 14126 |
| 14127 | 14127 |
| 14128 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 14128 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
| 14129 uword pc_offset = pc - EntryPoint(); | 14129 uword pc_offset = pc - PayloadStart(); |
| 14130 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 14130 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 14131 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 14131 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
| 14132 while (iter.MoveNext()) { | 14132 while (iter.MoveNext()) { |
| 14133 if (iter.PcOffset() == pc_offset) { | 14133 if (iter.PcOffset() == pc_offset) { |
| 14134 return iter.DeoptId(); | 14134 return iter.DeoptId(); |
| 14135 } | 14135 } |
| 14136 } | 14136 } |
| 14137 return Thread::kNoDeoptId; | 14137 return Thread::kNoDeoptId; |
| 14138 } | 14138 } |
| 14139 | 14139 |
| 14140 | 14140 |
| 14141 const char* Code::ToCString() const { | 14141 const char* Code::ToCString() const { |
| 14142 Zone* zone = Thread::Current()->zone(); | 14142 Zone* zone = Thread::Current()->zone(); |
| 14143 if (IsStubCode()) { | 14143 if (IsStubCode()) { |
| 14144 const char* name = StubCode::NameOfStub(EntryPoint()); | 14144 const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); |
| 14145 return zone->PrintToString("[stub: %s]", name); | 14145 return zone->PrintToString("[stub: %s]", name); |
| 14146 } else { | 14146 } else { |
| 14147 return zone->PrintToString("Code entry:%" Px, EntryPoint()); | 14147 return zone->PrintToString("Code entry:%" Px, UncheckedEntryPoint()); |
| 14148 } | 14148 } |
| 14149 } | 14149 } |
| 14150 | 14150 |
| 14151 | 14151 |
| 14152 RawString* Code::Name() const { | 14152 RawString* Code::Name() const { |
| 14153 const Object& obj = Object::Handle(owner()); | 14153 const Object& obj = Object::Handle(owner()); |
| 14154 if (obj.IsNull()) { | 14154 if (obj.IsNull()) { |
| 14155 // Regular stub. | 14155 // Regular stub. |
| 14156 Thread* thread = Thread::Current(); | 14156 Thread* thread = Thread::Current(); |
| 14157 Zone* zone = thread->zone(); | 14157 Zone* zone = thread->zone(); |
| 14158 const char* name = StubCode::NameOfStub(EntryPoint()); | 14158 const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); |
| 14159 ASSERT(name != NULL); | 14159 ASSERT(name != NULL); |
| 14160 char* stub_name = OS::SCreate(zone, | 14160 char* stub_name = OS::SCreate(zone, |
| 14161 "%s%s", Symbols::StubPrefix().ToCString(), name); | 14161 "%s%s", Symbols::StubPrefix().ToCString(), name); |
| 14162 return Symbols::New(thread, stub_name, strlen(stub_name)); | 14162 return Symbols::New(thread, stub_name, strlen(stub_name)); |
| 14163 } else if (obj.IsClass()) { | 14163 } else if (obj.IsClass()) { |
| 14164 // Allocation stub. | 14164 // Allocation stub. |
| 14165 Thread* thread = Thread::Current(); | 14165 Thread* thread = Thread::Current(); |
| 14166 Zone* zone = thread->zone(); | 14166 Zone* zone = thread->zone(); |
| 14167 const Class& cls = Class::Cast(obj); | 14167 const Class& cls = Class::Cast(obj); |
| 14168 String& cls_name = String::Handle(zone, cls.ScrubbedName()); | 14168 String& cls_name = String::Handle(zone, cls.ScrubbedName()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14227 #endif // !defined(TARGET_ARCH_DBC) | 14227 #endif // !defined(TARGET_ARCH_DBC) |
| 14228 } | 14228 } |
| 14229 | 14229 |
| 14230 | 14230 |
| 14231 void Code::SetActiveInstructions(RawInstructions* instructions) const { | 14231 void Code::SetActiveInstructions(RawInstructions* instructions) const { |
| 14232 DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); | 14232 DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); |
| 14233 // RawInstructions are never allocated in New space and hence a | 14233 // RawInstructions are never allocated in New space and hence a |
| 14234 // store buffer update is not needed here. | 14234 // store buffer update is not needed here. |
| 14235 StorePointer(&raw_ptr()->active_instructions_, instructions); | 14235 StorePointer(&raw_ptr()->active_instructions_, instructions); |
| 14236 StoreNonPointer(&raw_ptr()->entry_point_, | 14236 StoreNonPointer(&raw_ptr()->entry_point_, |
| 14237 reinterpret_cast<uword>(instructions->ptr()) + | 14237 Instructions::UncheckedEntryPoint(instructions)); |
| 14238 Instructions::HeaderSize()); | 14238 StoreNonPointer(&raw_ptr()->checked_entry_point_, |
| 14239 Instructions::CheckedEntryPoint(instructions)); |
| 14239 } | 14240 } |
| 14240 | 14241 |
| 14241 | 14242 |
| 14242 uword Code::GetLazyDeoptPc() const { | 14243 uword Code::GetLazyDeoptPc() const { |
| 14243 return (lazy_deopt_pc_offset() != kInvalidPc) | 14244 return (lazy_deopt_pc_offset() != kInvalidPc) |
| 14244 ? EntryPoint() + lazy_deopt_pc_offset() : 0; | 14245 ? PayloadStart() + lazy_deopt_pc_offset() : 0; |
| 14245 } | 14246 } |
| 14246 | 14247 |
| 14247 | 14248 |
| 14248 RawStackmap* Code::GetStackmap( | 14249 RawStackmap* Code::GetStackmap( |
| 14249 uint32_t pc_offset, Array* maps, Stackmap* map) const { | 14250 uint32_t pc_offset, Array* maps, Stackmap* map) const { |
| 14250 // This code is used during iterating frames during a GC and hence it | 14251 // This code is used during iterating frames during a GC and hence it |
| 14251 // should not in turn start a GC. | 14252 // should not in turn start a GC. |
| 14252 NoSafepointScope no_safepoint; | 14253 NoSafepointScope no_safepoint; |
| 14253 if (stackmaps() == Array::null()) { | 14254 if (stackmaps() == Array::null()) { |
| 14254 // No stack maps are present in the code object which means this | 14255 // No stack maps are present in the code object which means this |
| (...skipping 8093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22348 OS::SNPrint(chars, truncated_len, "%s", kTruncated); | 22349 OS::SNPrint(chars, truncated_len, "%s", kTruncated); |
| 22349 frame_strings.Add(chars); | 22350 frame_strings.Add(chars); |
| 22350 total_len += truncated_len; | 22351 total_len += truncated_len; |
| 22351 ASSERT(PcOffsetAtFrame(i) != Smi::null()); | 22352 ASSERT(PcOffsetAtFrame(i) != Smi::null()); |
| 22352 // To account for gap frames. | 22353 // To account for gap frames. |
| 22353 (*frame_index) += Smi::Value(PcOffsetAtFrame(i)); | 22354 (*frame_index) += Smi::Value(PcOffsetAtFrame(i)); |
| 22354 } | 22355 } |
| 22355 } else { | 22356 } else { |
| 22356 code = CodeAtFrame(i); | 22357 code = CodeAtFrame(i); |
| 22357 ASSERT(function.raw() == code.function()); | 22358 ASSERT(function.raw() == code.function()); |
| 22358 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); | 22359 uword pc = code.PayloadStart() + Smi::Value(PcOffsetAtFrame(i)); |
| 22359 if (code.is_optimized() && | 22360 if (code.is_optimized() && |
| 22360 expand_inlined() && | 22361 expand_inlined() && |
| 22361 !FLAG_precompiled_runtime) { | 22362 !FLAG_precompiled_runtime) { |
| 22362 // Traverse inlined frames. | 22363 // Traverse inlined frames. |
| 22363 for (InlinedFunctionsIterator it(code, pc); | 22364 for (InlinedFunctionsIterator it(code, pc); |
| 22364 !it.Done() && (*frame_index < max_frames); it.Advance()) { | 22365 !it.Done() && (*frame_index < max_frames); it.Advance()) { |
| 22365 function = it.function(); | 22366 function = it.function(); |
| 22366 if (function.is_visible() || FLAG_show_invisible_frames) { | 22367 if (function.is_visible() || FLAG_show_invisible_frames) { |
| 22367 code = it.code(); | 22368 code = it.code(); |
| 22368 ASSERT(function.raw() == code.function()); | 22369 ASSERT(function.raw() == code.function()); |
| 22369 uword pc = it.pc(); | 22370 uword pc = it.pc(); |
| 22370 ASSERT(pc != 0); | 22371 ASSERT(pc != 0); |
| 22371 ASSERT(code.EntryPoint() <= pc); | 22372 ASSERT(code.PayloadStart() <= pc); |
| 22372 ASSERT(pc < (code.EntryPoint() + code.Size())); | 22373 ASSERT(pc < (code.PayloadStart() + code.Size())); |
| 22373 total_len += PrintOneStacktrace( | 22374 total_len += PrintOneStacktrace( |
| 22374 zone, &frame_strings, pc, function, code, *frame_index); | 22375 zone, &frame_strings, pc, function, code, *frame_index); |
| 22375 (*frame_index)++; // To account for inlined frames. | 22376 (*frame_index)++; // To account for inlined frames. |
| 22376 } | 22377 } |
| 22377 } | 22378 } |
| 22378 } else { | 22379 } else { |
| 22379 if (function.is_visible() || FLAG_show_invisible_frames) { | 22380 if (function.is_visible() || FLAG_show_invisible_frames) { |
| 22380 total_len += PrintOneStacktrace( | 22381 total_len += PrintOneStacktrace( |
| 22381 zone, &frame_strings, pc, function, code, *frame_index); | 22382 zone, &frame_strings, pc, function, code, *frame_index); |
| 22382 (*frame_index)++; | 22383 (*frame_index)++; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22706 return UserTag::null(); | 22707 return UserTag::null(); |
| 22707 } | 22708 } |
| 22708 | 22709 |
| 22709 | 22710 |
| 22710 const char* UserTag::ToCString() const { | 22711 const char* UserTag::ToCString() const { |
| 22711 const String& tag_label = String::Handle(label()); | 22712 const String& tag_label = String::Handle(label()); |
| 22712 return tag_label.ToCString(); | 22713 return tag_label.ToCString(); |
| 22713 } | 22714 } |
| 22714 | 22715 |
| 22715 } // namespace dart | 22716 } // namespace dart |
| OLD | NEW |