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 2754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 virtual void IncrementInvalidationGen() { | 2805 virtual void IncrementInvalidationGen() { |
2805 Isolate::Current()->IncrCHAInvalidationGen(); | 2806 Isolate::Current()->IncrCHAInvalidationGen(); |
2806 } | 2807 } |
2807 | 2808 |
2808 private: | 2809 private: |
2809 const Class& cls_; | 2810 const Class& cls_; |
2810 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); | 2811 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); |
2811 }; | 2812 }; |
2812 | 2813 |
2813 | 2814 |
| 2815 #if defined(DEBUG) |
| 2816 static bool IsMutatorOrAtSafepoint() { |
| 2817 Thread* thread = Thread::Current(); |
| 2818 return thread->IsMutatorThread() || |
| 2819 thread->isolate()->thread_registry()->AtSafepoint(); |
| 2820 } |
| 2821 #endif |
| 2822 |
2814 void Class::RegisterCHACode(const Code& code) { | 2823 void Class::RegisterCHACode(const Code& code) { |
2815 if (FLAG_trace_cha) { | 2824 if (FLAG_trace_cha) { |
2816 THR_Print("RegisterCHACode %s class %s\n", | 2825 THR_Print("RegisterCHACode %s class %s\n", |
2817 Function::Handle(code.function()).ToQualifiedCString(), ToCString()); | 2826 Function::Handle(code.function()).ToQualifiedCString(), ToCString()); |
2818 } | 2827 } |
2819 ASSERT(Thread::Current()->IsMutatorThread()); | 2828 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
2820 ASSERT(code.is_optimized()); | 2829 ASSERT(code.is_optimized()); |
2821 CHACodeArray a(*this); | 2830 CHACodeArray a(*this); |
2822 a.Register(code); | 2831 a.Register(code); |
2823 } | 2832 } |
2824 | 2833 |
2825 | 2834 |
2826 void Class::DisableCHAOptimizedCode() { | 2835 void Class::DisableCHAOptimizedCode() { |
2827 ASSERT(Thread::Current()->IsMutatorThread()); | 2836 ASSERT(Thread::Current()->IsMutatorThread()); |
2828 CHACodeArray a(*this); | 2837 CHACodeArray a(*this); |
2829 a.DisableCode(); | 2838 a.DisableCode(); |
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5276 } | 5285 } |
5277 | 5286 |
5278 | 5287 |
5279 bool Function::HasBreakpoint() const { | 5288 bool Function::HasBreakpoint() const { |
5280 Thread* thread = Thread::Current(); | 5289 Thread* thread = Thread::Current(); |
5281 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); | 5290 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); |
5282 } | 5291 } |
5283 | 5292 |
5284 | 5293 |
5285 void Function::InstallOptimizedCode(const Code& code, bool is_osr) const { | 5294 void Function::InstallOptimizedCode(const Code& code, bool is_osr) const { |
5286 ASSERT(Thread::Current()->IsMutatorThread()); | 5295 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5287 // We may not have previous code if 'always_optimize' is set. | 5296 // We may not have previous code if 'always_optimize' is set. |
5288 if (!is_osr && HasCode()) { | 5297 if (!is_osr && HasCode()) { |
5289 Code::Handle(CurrentCode()).DisableDartCode(); | 5298 Code::Handle(CurrentCode()).DisableDartCode(); |
5290 } | 5299 } |
5291 AttachCode(code); | 5300 AttachCode(code); |
5292 } | 5301 } |
5293 | 5302 |
5294 | 5303 |
5295 void Function::SetInstructions(const Code& value) const { | 5304 void Function::SetInstructions(const Code& value) const { |
5296 ASSERT(Thread::Current()->IsMutatorThread()); | 5305 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5297 SetInstructionsSafe(value); | 5306 SetInstructionsSafe(value); |
5298 } | 5307 } |
5299 | 5308 |
5300 | 5309 |
5301 void Function::SetInstructionsSafe(const Code& value) const { | 5310 void Function::SetInstructionsSafe(const Code& value) const { |
5302 StorePointer(&raw_ptr()->code_, value.raw()); | 5311 StorePointer(&raw_ptr()->code_, value.raw()); |
5303 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); | 5312 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); |
5304 } | 5313 } |
5305 | 5314 |
5306 | 5315 |
5307 void Function::AttachCode(const Code& value) const { | 5316 void Function::AttachCode(const Code& value) const { |
5308 ASSERT(Thread::Current()->IsMutatorThread()); | 5317 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5309 // Finish setting up code before activating it. | 5318 // Finish setting up code before activating it. |
5310 value.set_owner(*this); | 5319 value.set_owner(*this); |
5311 SetInstructions(value); | 5320 SetInstructions(value); |
5312 ASSERT(Function::Handle(value.function()).IsNull() || | 5321 ASSERT(Function::Handle(value.function()).IsNull() || |
5313 (value.function() == this->raw())); | 5322 (value.function() == this->raw())); |
5314 } | 5323 } |
5315 | 5324 |
5316 | 5325 |
5317 bool Function::HasCode() const { | 5326 bool Function::HasCode() const { |
5318 ASSERT(raw_ptr()->code_ != Code::null()); | 5327 ASSERT(raw_ptr()->code_ != Code::null()); |
(...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7743 Isolate::Current()->IncrFieldInvalidationGen(); | 7752 Isolate::Current()->IncrFieldInvalidationGen(); |
7744 } | 7753 } |
7745 | 7754 |
7746 private: | 7755 private: |
7747 const Field& field_; | 7756 const Field& field_; |
7748 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); | 7757 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); |
7749 }; | 7758 }; |
7750 | 7759 |
7751 | 7760 |
7752 void Field::RegisterDependentCode(const Code& code) const { | 7761 void Field::RegisterDependentCode(const Code& code) const { |
7753 ASSERT(Thread::Current()->IsMutatorThread()); | 7762 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
7754 ASSERT(code.is_optimized()); | 7763 ASSERT(code.is_optimized()); |
7755 FieldDependentArray a(*this); | 7764 FieldDependentArray a(*this); |
7756 a.Register(code); | 7765 a.Register(code); |
7757 } | 7766 } |
7758 | 7767 |
7759 | 7768 |
7760 void Field::DeoptimizeDependentCode() const { | 7769 void Field::DeoptimizeDependentCode() const { |
7761 ASSERT(Thread::Current()->IsMutatorThread()); | 7770 ASSERT(Thread::Current()->IsMutatorThread()); |
7762 FieldDependentArray a(*this); | 7771 FieldDependentArray a(*this); |
7763 a.DisableCode(); | 7772 a.DisableCode(); |
(...skipping 5575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13339 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { | 13348 for (intptr_t i = 0; i < pointer_offsets.length(); i++) { |
13340 intptr_t offset_in_instrs = pointer_offsets[i]; | 13349 intptr_t offset_in_instrs = pointer_offsets[i]; |
13341 code.SetPointerOffsetAt(i, offset_in_instrs); | 13350 code.SetPointerOffsetAt(i, offset_in_instrs); |
13342 uword addr = region.start() + offset_in_instrs; | 13351 uword addr = region.start() + offset_in_instrs; |
13343 const Object* object = *reinterpret_cast<Object**>(addr); | 13352 const Object* object = *reinterpret_cast<Object**>(addr); |
13344 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr), | 13353 instrs.raw()->StorePointer(reinterpret_cast<RawObject**>(addr), |
13345 object->raw()); | 13354 object->raw()); |
13346 } | 13355 } |
13347 | 13356 |
13348 // Hook up Code and Instructions objects. | 13357 // Hook up Code and Instructions objects. |
13349 code.set_active_instructions(instrs.raw()); | 13358 code.SetActiveInstructions(instrs.raw()); |
13350 code.set_instructions(instrs.raw()); | 13359 code.set_instructions(instrs.raw()); |
13351 code.set_is_alive(true); | 13360 code.set_is_alive(true); |
13352 | 13361 |
13353 // Set object pool in Instructions object. | 13362 // Set object pool in Instructions object. |
13354 INC_STAT(Thread::Current(), | 13363 INC_STAT(Thread::Current(), |
13355 total_code_size, object_pool.Length() * sizeof(uintptr_t)); | 13364 total_code_size, object_pool.Length() * sizeof(uintptr_t)); |
13356 code.set_object_pool(object_pool.raw()); | 13365 code.set_object_pool(object_pool.raw()); |
13357 | 13366 |
13358 if (FLAG_write_protect_code) { | 13367 if (FLAG_write_protect_code) { |
13359 uword address = RawObject::ToAddr(instrs.raw()); | 13368 uword address = RawObject::ToAddr(instrs.raw()); |
(...skipping 21 matching lines...) Expand all Loading... |
13381 RawCode* Code::FinalizeCode(const Function& function, | 13390 RawCode* Code::FinalizeCode(const Function& function, |
13382 Assembler* assembler, | 13391 Assembler* assembler, |
13383 bool optimized) { | 13392 bool optimized) { |
13384 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 13393 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |
13385 // try to avoid it. | 13394 // try to avoid it. |
13386 if (CodeObservers::AreActive()) { | 13395 if (CodeObservers::AreActive()) { |
13387 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), | 13396 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), |
13388 assembler, | 13397 assembler, |
13389 optimized); | 13398 optimized); |
13390 } else { | 13399 } else { |
13391 return FinalizeCode("", assembler); | 13400 return FinalizeCode("", assembler, optimized); |
13392 } | 13401 } |
13393 } | 13402 } |
13394 | 13403 |
13395 | 13404 |
13396 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { | 13405 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { |
13397 return RawCode::ContainsPC(raw_obj, pc_); | 13406 return RawCode::ContainsPC(raw_obj, pc_); |
13398 } | 13407 } |
13399 | 13408 |
13400 | 13409 |
13401 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { | 13410 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13551 } | 13560 } |
13552 | 13561 |
13553 | 13562 |
13554 bool Code::IsFunctionCode() const { | 13563 bool Code::IsFunctionCode() const { |
13555 const Object& obj = Object::Handle(owner()); | 13564 const Object& obj = Object::Handle(owner()); |
13556 return obj.IsFunction(); | 13565 return obj.IsFunction(); |
13557 } | 13566 } |
13558 | 13567 |
13559 | 13568 |
13560 void Code::DisableDartCode() const { | 13569 void Code::DisableDartCode() const { |
13561 ASSERT(Thread::Current()->IsMutatorThread()); | 13570 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
13562 ASSERT(IsFunctionCode()); | 13571 ASSERT(IsFunctionCode()); |
13563 ASSERT(instructions() == active_instructions()); | 13572 ASSERT(instructions() == active_instructions()); |
13564 const Code& new_code = | 13573 const Code& new_code = |
13565 Code::Handle(StubCode::FixCallersTarget_entry()->code()); | 13574 Code::Handle(StubCode::FixCallersTarget_entry()->code()); |
13566 set_active_instructions(new_code.instructions()); | 13575 SetActiveInstructions(new_code.instructions()); |
13567 } | 13576 } |
13568 | 13577 |
13569 | 13578 |
13570 void Code::DisableStubCode() const { | 13579 void Code::DisableStubCode() const { |
13571 ASSERT(Thread::Current()->IsMutatorThread()); | 13580 ASSERT(Thread::Current()->IsMutatorThread()); |
13572 ASSERT(IsAllocationStubCode()); | 13581 ASSERT(IsAllocationStubCode()); |
13573 ASSERT(instructions() == active_instructions()); | 13582 ASSERT(instructions() == active_instructions()); |
13574 const Code& new_code = | 13583 const Code& new_code = |
13575 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); | 13584 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); |
13576 set_active_instructions(new_code.instructions()); | 13585 SetActiveInstructions(new_code.instructions()); |
13577 } | 13586 } |
13578 | 13587 |
13579 | 13588 |
| 13589 void Code::SetActiveInstructions(RawInstructions* instructions) const { |
| 13590 DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); |
| 13591 // RawInstructions are never allocated in New space and hence a |
| 13592 // store buffer update is not needed here. |
| 13593 StorePointer(&raw_ptr()->active_instructions_, instructions); |
| 13594 StoreNonPointer(&raw_ptr()->entry_point_, |
| 13595 reinterpret_cast<uword>(instructions->ptr()) + |
| 13596 Instructions::HeaderSize()); |
| 13597 } |
| 13598 |
| 13599 |
13580 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { | 13600 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { |
13581 JSONObject jsobj(stream); | 13601 JSONObject jsobj(stream); |
13582 AddCommonObjectProperties(&jsobj, "Code", ref); | 13602 AddCommonObjectProperties(&jsobj, "Code", ref); |
13583 jsobj.AddFixedServiceId("code/%" Px64"-%" Px "", | 13603 jsobj.AddFixedServiceId("code/%" Px64"-%" Px "", |
13584 compile_timestamp(), | 13604 compile_timestamp(), |
13585 EntryPoint()); | 13605 EntryPoint()); |
13586 const String& user_name = String::Handle(PrettyName()); | 13606 const String& user_name = String::Handle(PrettyName()); |
13587 const String& vm_name = String::Handle(Name()); | 13607 const String& vm_name = String::Handle(Name()); |
13588 AddNameProperties(&jsobj, user_name, vm_name); | 13608 AddNameProperties(&jsobj, user_name, vm_name); |
13589 const bool is_stub = IsStubCode() || IsAllocationStubCode(); | 13609 const bool is_stub = IsStubCode() || IsAllocationStubCode(); |
(...skipping 8305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21895 return tag_label.ToCString(); | 21915 return tag_label.ToCString(); |
21896 } | 21916 } |
21897 | 21917 |
21898 | 21918 |
21899 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21919 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
21900 Instance::PrintJSONImpl(stream, ref); | 21920 Instance::PrintJSONImpl(stream, ref); |
21901 } | 21921 } |
21902 | 21922 |
21903 | 21923 |
21904 } // namespace dart | 21924 } // namespace dart |
OLD | NEW |