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 19 matching lines...) Expand all Loading... | |
30 #include "vm/object_store.h" | 30 #include "vm/object_store.h" |
31 #include "vm/parser.h" | 31 #include "vm/parser.h" |
32 #include "vm/profiler.h" | 32 #include "vm/profiler.h" |
33 #include "vm/report.h" | 33 #include "vm/report.h" |
34 #include "vm/reusable_handles.h" | 34 #include "vm/reusable_handles.h" |
35 #include "vm/runtime_entry.h" | 35 #include "vm/runtime_entry.h" |
36 #include "vm/scopes.h" | 36 #include "vm/scopes.h" |
37 #include "vm/stack_frame.h" | 37 #include "vm/stack_frame.h" |
38 #include "vm/symbols.h" | 38 #include "vm/symbols.h" |
39 #include "vm/tags.h" | 39 #include "vm/tags.h" |
40 #include "vm/thread_registry.h" | |
40 #include "vm/timer.h" | 41 #include "vm/timer.h" |
41 #include "vm/unicode.h" | 42 #include "vm/unicode.h" |
42 #include "vm/verified_memory.h" | 43 #include "vm/verified_memory.h" |
43 #include "vm/weak_code.h" | 44 #include "vm/weak_code.h" |
44 | 45 |
45 namespace dart { | 46 namespace dart { |
46 | 47 |
47 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, | 48 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
48 "Huge method cutoff in unoptimized code size (in bytes)."); | 49 "Huge method cutoff in unoptimized code size (in bytes)."); |
49 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, | 50 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, |
(...skipping 2832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2882 const Class& cls_; | 2883 const Class& cls_; |
2883 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); | 2884 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); |
2884 }; | 2885 }; |
2885 | 2886 |
2886 | 2887 |
2887 void Class::RegisterCHACode(const Code& code) { | 2888 void Class::RegisterCHACode(const Code& code) { |
2888 if (FLAG_trace_cha) { | 2889 if (FLAG_trace_cha) { |
2889 THR_Print("RegisterCHACode %s class %s\n", | 2890 THR_Print("RegisterCHACode %s class %s\n", |
2890 Function::Handle(code.function()).ToQualifiedCString(), ToCString()); | 2891 Function::Handle(code.function()).ToQualifiedCString(), ToCString()); |
2891 } | 2892 } |
2892 ASSERT(Thread::Current()->IsMutatorThread()); | 2893 ASSERT(Thread::Current()->IsMutatorThread() || |
2894 Isolate::Current()->thread_registry()->InSafepoint()); | |
siva
2015/11/18 17:46:27
I wonder if it will be more efficient to do:
#if d
srdjan
2015/11/18 19:04:53
Factoring this out into (in object.cc):
static bo
| |
2893 ASSERT(code.is_optimized()); | 2895 ASSERT(code.is_optimized()); |
2894 CHACodeArray a(*this); | 2896 CHACodeArray a(*this); |
2895 a.Register(code); | 2897 a.Register(code); |
2896 } | 2898 } |
2897 | 2899 |
2898 | 2900 |
2899 void Class::DisableCHAOptimizedCode() { | 2901 void Class::DisableCHAOptimizedCode() { |
2900 ASSERT(Thread::Current()->IsMutatorThread()); | 2902 ASSERT(Thread::Current()->IsMutatorThread()); |
2901 CHACodeArray a(*this); | 2903 CHACodeArray a(*this); |
2902 a.DisableCode(); | 2904 a.DisableCode(); |
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5349 } | 5351 } |
5350 | 5352 |
5351 | 5353 |
5352 bool Function::HasBreakpoint() const { | 5354 bool Function::HasBreakpoint() const { |
5353 Thread* thread = Thread::Current(); | 5355 Thread* thread = Thread::Current(); |
5354 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); | 5356 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); |
5355 } | 5357 } |
5356 | 5358 |
5357 | 5359 |
5358 void Function::InstallOptimizedCode(const Code& code, bool is_osr) const { | 5360 void Function::InstallOptimizedCode(const Code& code, bool is_osr) const { |
5359 ASSERT(Thread::Current()->IsMutatorThread()); | 5361 ASSERT(Thread::Current()->IsMutatorThread() || |
5362 Isolate::Current()->thread_registry()->InSafepoint()); | |
5360 // We may not have previous code if 'always_optimize' is set. | 5363 // We may not have previous code if 'always_optimize' is set. |
5361 if (!is_osr && HasCode()) { | 5364 if (!is_osr && HasCode()) { |
5362 Code::Handle(CurrentCode()).DisableDartCode(); | 5365 Code::Handle(CurrentCode()).DisableDartCode(); |
5363 } | 5366 } |
5364 AttachCode(code); | 5367 AttachCode(code); |
5365 } | 5368 } |
5366 | 5369 |
5367 | 5370 |
5368 void Function::SetInstructions(const Code& value) const { | 5371 void Function::SetInstructions(const Code& value) const { |
5369 ASSERT(Thread::Current()->IsMutatorThread()); | 5372 ASSERT(Thread::Current()->IsMutatorThread() || |
5373 Isolate::Current()->thread_registry()->InSafepoint()); | |
5370 SetInstructionsSafe(value); | 5374 SetInstructionsSafe(value); |
5371 } | 5375 } |
5372 | 5376 |
5373 | 5377 |
5374 void Function::SetInstructionsSafe(const Code& value) const { | 5378 void Function::SetInstructionsSafe(const Code& value) const { |
5375 StorePointer(&raw_ptr()->code_, value.raw()); | 5379 StorePointer(&raw_ptr()->code_, value.raw()); |
5376 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); | 5380 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); |
5377 } | 5381 } |
5378 | 5382 |
5379 | 5383 |
5380 void Function::AttachCode(const Code& value) const { | 5384 void Function::AttachCode(const Code& value) const { |
5381 ASSERT(Thread::Current()->IsMutatorThread()); | 5385 ASSERT(Thread::Current()->IsMutatorThread() || |
5386 Isolate::Current()->thread_registry()->InSafepoint()); | |
5382 // Finish setting up code before activating it. | 5387 // Finish setting up code before activating it. |
5383 value.set_owner(*this); | 5388 value.set_owner(*this); |
5384 SetInstructions(value); | 5389 SetInstructions(value); |
5385 ASSERT(Function::Handle(value.function()).IsNull() || | 5390 ASSERT(Function::Handle(value.function()).IsNull() || |
5386 (value.function() == this->raw())); | 5391 (value.function() == this->raw())); |
5387 } | 5392 } |
5388 | 5393 |
5389 | 5394 |
5390 bool Function::HasCode() const { | 5395 bool Function::HasCode() const { |
5391 ASSERT(raw_ptr()->code_ != Code::null()); | 5396 ASSERT(raw_ptr()->code_ != Code::null()); |
(...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7816 Isolate::Current()->IncrFieldInvalidationGen(); | 7821 Isolate::Current()->IncrFieldInvalidationGen(); |
7817 } | 7822 } |
7818 | 7823 |
7819 private: | 7824 private: |
7820 const Field& field_; | 7825 const Field& field_; |
7821 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); | 7826 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); |
7822 }; | 7827 }; |
7823 | 7828 |
7824 | 7829 |
7825 void Field::RegisterDependentCode(const Code& code) const { | 7830 void Field::RegisterDependentCode(const Code& code) const { |
7826 ASSERT(Thread::Current()->IsMutatorThread()); | 7831 ASSERT(Thread::Current()->IsMutatorThread() || |
7832 Isolate::Current()->thread_registry()->InSafepoint()); | |
7827 ASSERT(code.is_optimized()); | 7833 ASSERT(code.is_optimized()); |
7828 FieldDependentArray a(*this); | 7834 FieldDependentArray a(*this); |
7829 a.Register(code); | 7835 a.Register(code); |
7830 } | 7836 } |
7831 | 7837 |
7832 | 7838 |
7833 void Field::DeoptimizeDependentCode() const { | 7839 void Field::DeoptimizeDependentCode() const { |
7834 ASSERT(Thread::Current()->IsMutatorThread()); | 7840 ASSERT(Thread::Current()->IsMutatorThread()); |
7835 FieldDependentArray a(*this); | 7841 FieldDependentArray a(*this); |
7836 a.DisableCode(); | 7842 a.DisableCode(); |
(...skipping 5575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13412 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { | 13418 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { |
13413 intptr_t offset_in_instrs = pointer_offsets[i]; | 13419 intptr_t offset_in_instrs = pointer_offsets[i]; |
13414 code.SetPointerOffsetAt(i, offset_in_instrs); | 13420 code.SetPointerOffsetAt(i, offset_in_instrs); |
13415 uword addr = region.start() + offset_in_instrs; | 13421 uword addr = region.start() + offset_in_instrs; |
13416 const Object* object = *reinterpret_cast<Object**>(addr); | 13422 const Object* object = *reinterpret_cast<Object**>(addr); |
13417 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr), | 13423 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr), |
13418 object->raw()); | 13424 object->raw()); |
13419 } | 13425 } |
13420 | 13426 |
13421 // Hook up Code and Instructions objects. | 13427 // Hook up Code and Instructions objects. |
13422 code.set_active_instructions(instrs.raw()); | 13428 code.SetActiveInstructions(instrs.raw()); |
13423 code.set_instructions(instrs.raw()); | 13429 code.set_instructions(instrs.raw()); |
13424 code.set_is_alive(true); | 13430 code.set_is_alive(true); |
13425 | 13431 |
13426 // Set object pool in Instructions object. | 13432 // Set object pool in Instructions object. |
13427 INC_STAT(Thread::Current(), | 13433 INC_STAT(Thread::Current(), |
13428 total_code_size, object_pool.Length() * sizeof(uintptr_t)); | 13434 total_code_size, object_pool.Length() * sizeof(uintptr_t)); |
13429 code.set_object_pool(object_pool.raw()); | 13435 code.set_object_pool(object_pool.raw()); |
13430 | 13436 |
13431 if (FLAG_write_protect_code) { | 13437 if (FLAG_write_protect_code) { |
13432 uword address = RawObject::ToAddr(instrs.raw()); | 13438 uword address = RawObject::ToAddr(instrs.raw()); |
(...skipping 21 matching lines...) Expand all Loading... | |
13454 RawCode* Code::FinalizeCode(const Function& function, | 13460 RawCode* Code::FinalizeCode(const Function& function, |
13455 Assembler* assembler, | 13461 Assembler* assembler, |
13456 bool optimized) { | 13462 bool optimized) { |
13457 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 13463 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |
13458 // try to avoid it. | 13464 // try to avoid it. |
13459 if (CodeObservers::AreActive()) { | 13465 if (CodeObservers::AreActive()) { |
13460 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), | 13466 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), |
13461 assembler, | 13467 assembler, |
13462 optimized); | 13468 optimized); |
13463 } else { | 13469 } else { |
13464 return FinalizeCode("", assembler); | 13470 return FinalizeCode("", assembler, optimized); |
13465 } | 13471 } |
13466 } | 13472 } |
13467 | 13473 |
13468 | 13474 |
13469 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { | 13475 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { |
13470 return RawCode::ContainsPC(raw_obj, pc_); | 13476 return RawCode::ContainsPC(raw_obj, pc_); |
13471 } | 13477 } |
13472 | 13478 |
13473 | 13479 |
13474 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { | 13480 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13624 } | 13630 } |
13625 | 13631 |
13626 | 13632 |
13627 bool Code::IsFunctionCode() const { | 13633 bool Code::IsFunctionCode() const { |
13628 const Object& obj = Object::Handle(owner()); | 13634 const Object& obj = Object::Handle(owner()); |
13629 return obj.IsFunction(); | 13635 return obj.IsFunction(); |
13630 } | 13636 } |
13631 | 13637 |
13632 | 13638 |
13633 void Code::DisableDartCode() const { | 13639 void Code::DisableDartCode() const { |
13634 ASSERT(Thread::Current()->IsMutatorThread()); | 13640 ASSERT(Thread::Current()->IsMutatorThread() || |
13641 Isolate::Current()->thread_registry()->InSafepoint()); | |
13635 ASSERT(IsFunctionCode()); | 13642 ASSERT(IsFunctionCode()); |
13636 ASSERT(instructions() == active_instructions()); | 13643 ASSERT(instructions() == active_instructions()); |
13637 const Code& new_code = | 13644 const Code& new_code = |
13638 Code::Handle(StubCode::FixCallersTarget_entry()->code()); | 13645 Code::Handle(StubCode::FixCallersTarget_entry()->code()); |
13639 set_active_instructions(new_code.instructions()); | 13646 SetActiveInstructions(new_code.instructions()); |
13640 } | 13647 } |
13641 | 13648 |
13642 | 13649 |
13643 void Code::DisableStubCode() const { | 13650 void Code::DisableStubCode() const { |
13644 ASSERT(Thread::Current()->IsMutatorThread()); | 13651 ASSERT(Thread::Current()->IsMutatorThread()); |
13645 ASSERT(IsAllocationStubCode()); | 13652 ASSERT(IsAllocationStubCode()); |
13646 ASSERT(instructions() == active_instructions()); | 13653 ASSERT(instructions() == active_instructions()); |
13647 const Code& new_code = | 13654 const Code& new_code = |
13648 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); | 13655 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); |
13649 set_active_instructions(new_code.instructions()); | 13656 SetActiveInstructions(new_code.instructions()); |
13650 } | 13657 } |
13651 | 13658 |
13652 | 13659 |
13660 void Code::SetActiveInstructions(RawInstructions* instructions) const { | |
13661 ASSERT(Thread::Current()->IsMutatorThread() || | |
13662 Isolate::Current()->thread_registry()->InSafepoint() || | |
13663 !is_alive()); | |
13664 // RawInstructions are never allocated in New space and hence a | |
13665 // store buffer update is not needed here. | |
13666 StorePointer(&raw_ptr()->active_instructions_, instructions); | |
13667 StoreNonPointer(&raw_ptr()->entry_point_, | |
13668 reinterpret_cast<uword>(instructions->ptr()) + | |
13669 Instructions::HeaderSize()); | |
13670 } | |
13671 | |
13672 | |
13653 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { | 13673 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { |
13654 JSONObject jsobj(stream); | 13674 JSONObject jsobj(stream); |
13655 AddCommonObjectProperties(&jsobj, "Code", ref); | 13675 AddCommonObjectProperties(&jsobj, "Code", ref); |
13656 jsobj.AddFixedServiceId("code/%" Px64"-%" Px "", | 13676 jsobj.AddFixedServiceId("code/%" Px64"-%" Px "", |
13657 compile_timestamp(), | 13677 compile_timestamp(), |
13658 EntryPoint()); | 13678 EntryPoint()); |
13659 const String& user_name = String::Handle(PrettyName()); | 13679 const String& user_name = String::Handle(PrettyName()); |
13660 const String& vm_name = String::Handle(Name()); | 13680 const String& vm_name = String::Handle(Name()); |
13661 AddNameProperties(&jsobj, user_name, vm_name); | 13681 AddNameProperties(&jsobj, user_name, vm_name); |
13662 const bool is_stub = IsStubCode() || IsAllocationStubCode(); | 13682 const bool is_stub = IsStubCode() || IsAllocationStubCode(); |
(...skipping 8305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
21968 return tag_label.ToCString(); | 21988 return tag_label.ToCString(); |
21969 } | 21989 } |
21970 | 21990 |
21971 | 21991 |
21972 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21992 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
21973 Instance::PrintJSONImpl(stream, ref); | 21993 Instance::PrintJSONImpl(stream, ref); |
21974 } | 21994 } |
21975 | 21995 |
21976 | 21996 |
21977 } // namespace dart | 21997 } // namespace dart |
OLD | NEW |