| 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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 } | 660 } |
| 661 | 661 |
| 662 // Allocate and initialize the empty_descriptors instance. | 662 // Allocate and initialize the empty_descriptors instance. |
| 663 { | 663 { |
| 664 uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); | 664 uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); |
| 665 InitializeObject(address, kPcDescriptorsCid, | 665 InitializeObject(address, kPcDescriptorsCid, |
| 666 PcDescriptors::InstanceSize(0)); | 666 PcDescriptors::InstanceSize(0)); |
| 667 PcDescriptors::initializeHandle( | 667 PcDescriptors::initializeHandle( |
| 668 empty_descriptors_, | 668 empty_descriptors_, |
| 669 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag)); | 669 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag)); |
| 670 empty_descriptors_->raw_ptr()->length_ = Smi::New(0); | 670 empty_descriptors_->raw_ptr()->length_ = 0; |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 cls = Class::New<Instance>(kDynamicCid); | 674 cls = Class::New<Instance>(kDynamicCid); |
| 675 cls.set_is_abstract(); | 675 cls.set_is_abstract(); |
| 676 cls.set_num_type_arguments(0); | 676 cls.set_num_type_arguments(0); |
| 677 cls.set_num_own_type_arguments(0); | 677 cls.set_num_own_type_arguments(0); |
| 678 cls.set_is_type_finalized(); | 678 cls.set_is_type_finalized(); |
| 679 cls.set_is_finalized(); | 679 cls.set_is_finalized(); |
| 680 dynamic_class_ = cls.raw(); | 680 dynamic_class_ = cls.raw(); |
| (...skipping 4112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4793 void PatchClass::set_source_class(const Class& value) const { | 4793 void PatchClass::set_source_class(const Class& value) const { |
| 4794 StorePointer(&raw_ptr()->source_class_, value.raw()); | 4794 StorePointer(&raw_ptr()->source_class_, value.raw()); |
| 4795 } | 4795 } |
| 4796 | 4796 |
| 4797 | 4797 |
| 4798 bool Function::HasBreakpoint() const { | 4798 bool Function::HasBreakpoint() const { |
| 4799 return Isolate::Current()->debugger()->HasBreakpoint(*this); | 4799 return Isolate::Current()->debugger()->HasBreakpoint(*this); |
| 4800 } | 4800 } |
| 4801 | 4801 |
| 4802 | 4802 |
| 4803 void Function::SetCode(const Code& value) const { | 4803 void Function::set_code(const Code& value) const { |
| 4804 StorePointer(&raw_ptr()->code_, value.raw()); | 4804 StorePointer(&raw_ptr()->code_, value.raw()); |
| 4805 } |
| 4806 |
| 4807 void Function::AttachCode(const Code& value) const { |
| 4808 set_code(value); |
| 4805 ASSERT(Function::Handle(value.function()).IsNull() || | 4809 ASSERT(Function::Handle(value.function()).IsNull() || |
| 4806 (value.function() == this->raw())); | 4810 (value.function() == this->raw())); |
| 4807 value.set_owner(*this); | 4811 value.set_owner(*this); |
| 4808 } | 4812 } |
| 4809 | 4813 |
| 4810 | 4814 |
| 4815 bool Function::HasCode() const { |
| 4816 ASSERT(raw_ptr()->code_ != Code::null()); |
| 4817 return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); |
| 4818 } |
| 4819 |
| 4820 |
| 4811 void Function::ClearCode() const { | 4821 void Function::ClearCode() const { |
| 4812 StorePointer(&raw_ptr()->code_, Code::null()); | 4822 StorePointer(&raw_ptr()->code_, StubCode::LazyCompile_entry()->code()); |
| 4813 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); | 4823 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); |
| 4814 } | 4824 } |
| 4815 | 4825 |
| 4816 | 4826 |
| 4817 void Function::SwitchToUnoptimizedCode() const { | 4827 void Function::SwitchToUnoptimizedCode() const { |
| 4818 ASSERT(HasOptimizedCode()); | 4828 ASSERT(HasOptimizedCode()); |
| 4819 | 4829 |
| 4820 const Code& current_code = Code::Handle(CurrentCode()); | 4830 const Code& current_code = Code::Handle(CurrentCode()); |
| 4821 | 4831 |
| 4822 // Optimized code object might have been actually fully produced by the | 4832 // Optimized code object might have been actually fully produced by the |
| 4823 // intrinsifier in this case nothing has to be done. In fact an attempt to | 4833 // intrinsifier in this case nothing has to be done. In fact an attempt to |
| 4824 // patch such code will cause crash. | 4834 // patch such code will cause crash. |
| 4825 // TODO(vegorov): if intrisifier can fully intrinsify the function then we | 4835 // TODO(vegorov): if intrisifier can fully intrinsify the function then we |
| 4826 // should not later try to optimize it. | 4836 // should not later try to optimize it. |
| 4827 if (PcDescriptors::Handle(current_code.pc_descriptors()).Length() == 0) { | 4837 if (PcDescriptors::Handle(current_code.pc_descriptors()).Length() == 0) { |
| 4828 return; | 4838 return; |
| 4829 } | 4839 } |
| 4830 | 4840 |
| 4831 if (FLAG_trace_disabling_optimized_code) { | 4841 if (FLAG_trace_disabling_optimized_code) { |
| 4832 OS::Print("Disabling optimized code: '%s' entry: %#" Px "\n", | 4842 OS::Print("Disabling optimized code: '%s' entry: %#" Px "\n", |
| 4833 ToFullyQualifiedCString(), | 4843 ToFullyQualifiedCString(), |
| 4834 current_code.EntryPoint()); | 4844 current_code.EntryPoint()); |
| 4835 } | 4845 } |
| 4836 // Patch entry of the optimized code. | 4846 // Patch entry of the optimized code. |
| 4837 CodePatcher::PatchEntry(current_code); | 4847 CodePatcher::PatchEntry(current_code); |
| 4838 // Use previously compiled unoptimized code. | 4848 // Use previously compiled unoptimized code. |
| 4839 SetCode(Code::Handle(unoptimized_code())); | 4849 AttachCode(Code::Handle(unoptimized_code())); |
| 4840 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code())); | 4850 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code())); |
| 4841 } | 4851 } |
| 4842 | 4852 |
| 4843 | 4853 |
| 4844 void Function::set_unoptimized_code(const Code& value) const { | 4854 void Function::set_unoptimized_code(const Code& value) const { |
| 4845 ASSERT(!value.is_optimized()); | 4855 ASSERT(!value.is_optimized()); |
| 4846 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); | 4856 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); |
| 4847 } | 4857 } |
| 4848 | 4858 |
| 4849 | 4859 |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5846 result.set_deoptimization_counter(0); | 5856 result.set_deoptimization_counter(0); |
| 5847 result.set_optimized_instruction_count(0); | 5857 result.set_optimized_instruction_count(0); |
| 5848 result.set_optimized_call_site_count(0); | 5858 result.set_optimized_call_site_count(0); |
| 5849 result.set_is_optimizable(is_native ? false : true); | 5859 result.set_is_optimizable(is_native ? false : true); |
| 5850 result.set_is_inlinable(true); | 5860 result.set_is_inlinable(true); |
| 5851 result.set_allows_hoisting_check_class(true); | 5861 result.set_allows_hoisting_check_class(true); |
| 5852 if (kind == RawFunction::kClosureFunction) { | 5862 if (kind == RawFunction::kClosureFunction) { |
| 5853 const ClosureData& data = ClosureData::Handle(ClosureData::New()); | 5863 const ClosureData& data = ClosureData::Handle(ClosureData::New()); |
| 5854 result.set_data(data); | 5864 result.set_data(data); |
| 5855 } | 5865 } |
| 5866 result.set_code(Code::Handle(StubCode::LazyCompile_entry()->code())); |
| 5856 return result.raw(); | 5867 return result.raw(); |
| 5857 } | 5868 } |
| 5858 | 5869 |
| 5859 | 5870 |
| 5860 RawFunction* Function::Clone(const Class& new_owner) const { | 5871 RawFunction* Function::Clone(const Class& new_owner) const { |
| 5861 ASSERT(!IsConstructor()); | 5872 ASSERT(!IsConstructor()); |
| 5862 Function& clone = Function::Handle(); | 5873 Function& clone = Function::Handle(); |
| 5863 clone ^= Object::Clone(*this, Heap::kOld); | 5874 clone ^= Object::Clone(*this, Heap::kOld); |
| 5864 const Class& origin = Class::Handle(this->origin()); | 5875 const Class& origin = Class::Handle(this->origin()); |
| 5865 const PatchClass& clone_owner = | 5876 const PatchClass& clone_owner = |
| 5866 PatchClass::Handle(PatchClass::New(new_owner, origin)); | 5877 PatchClass::Handle(PatchClass::New(new_owner, origin)); |
| 5867 clone.set_owner(clone_owner); | 5878 clone.set_owner(clone_owner); |
| 5868 clone.StorePointer(&clone.raw_ptr()->code_, Code::null()); | 5879 clone.ClearCode(); |
| 5869 clone.StorePointer(&clone.raw_ptr()->unoptimized_code_, Code::null()); | |
| 5870 clone.set_usage_counter(0); | 5880 clone.set_usage_counter(0); |
| 5871 clone.set_deoptimization_counter(0); | 5881 clone.set_deoptimization_counter(0); |
| 5872 clone.set_optimized_instruction_count(0); | 5882 clone.set_optimized_instruction_count(0); |
| 5873 clone.set_optimized_call_site_count(0); | 5883 clone.set_optimized_call_site_count(0); |
| 5874 return clone.raw(); | 5884 return clone.raw(); |
| 5875 } | 5885 } |
| 5876 | 5886 |
| 5877 | 5887 |
| 5878 RawFunction* Function::NewClosureFunction(const String& name, | 5888 RawFunction* Function::NewClosureFunction(const String& name, |
| 5879 const Function& parent, | 5889 const Function& parent, |
| 5880 intptr_t token_pos) { | 5890 intptr_t token_pos) { |
| 5881 ASSERT(!parent.IsNull()); | 5891 ASSERT(!parent.IsNull()); |
| 5882 // Use the owner defining the parent function and not the class containing it. | 5892 // Use the owner defining the parent function and not the class containing it. |
| 5883 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); | 5893 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); |
| 5884 ASSERT(!parent_owner.IsNull()); | 5894 ASSERT(!parent_owner.IsNull()); |
| 5885 const Function& result = Function::Handle( | 5895 const Function& result = Function::Handle( |
| 5886 Function::New(name, | 5896 Function::New(name, |
| 5887 RawFunction::kClosureFunction, | 5897 RawFunction::kClosureFunction, |
| 5888 /* is_static = */ parent.is_static(), | 5898 /* is_static = */ parent.is_static(), |
| 5889 /* is_const = */ false, | 5899 /* is_const = */ false, |
| 5890 /* is_abstract = */ false, | 5900 /* is_abstract = */ false, |
| 5891 /* is_external = */ false, | 5901 /* is_external = */ false, |
| 5892 parent.is_native(), | 5902 parent.is_native(), |
| 5893 parent_owner, | 5903 parent_owner, |
| 5894 token_pos)); | 5904 token_pos)); |
| 5895 result.set_parent_function(parent); | 5905 result.set_parent_function(parent); |
| 5906 |
| 5896 return result.raw(); | 5907 return result.raw(); |
| 5897 } | 5908 } |
| 5898 | 5909 |
| 5899 | 5910 |
| 5900 RawFunction* Function::ImplicitClosureFunction() const { | 5911 RawFunction* Function::ImplicitClosureFunction() const { |
| 5901 // Return the existing implicit closure function if any. | 5912 // Return the existing implicit closure function if any. |
| 5902 if (implicit_closure_function() != Function::null()) { | 5913 if (implicit_closure_function() != Function::null()) { |
| 5903 return implicit_closure_function(); | 5914 return implicit_closure_function(); |
| 5904 } | 5915 } |
| 5905 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); | 5916 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); |
| (...skipping 3885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9791 return "Instructions"; | 9802 return "Instructions"; |
| 9792 } | 9803 } |
| 9793 | 9804 |
| 9794 | 9805 |
| 9795 void Instructions::PrintToJSONStream(JSONStream* stream, bool ref) const { | 9806 void Instructions::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 9796 Object::PrintToJSONStream(stream, ref); | 9807 Object::PrintToJSONStream(stream, ref); |
| 9797 } | 9808 } |
| 9798 | 9809 |
| 9799 | 9810 |
| 9800 intptr_t PcDescriptors::Length() const { | 9811 intptr_t PcDescriptors::Length() const { |
| 9801 return Smi::Value(raw_ptr()->length_); | 9812 return raw_ptr()->length_; |
| 9802 } | 9813 } |
| 9803 | 9814 |
| 9804 | 9815 |
| 9805 void PcDescriptors::SetLength(intptr_t value) const { | 9816 void PcDescriptors::SetLength(intptr_t value) const { |
| 9806 // This is only safe because we create a new Smi, which does not cause | 9817 raw_ptr()->length_ = value; |
| 9807 // heap allocation. | |
| 9808 raw_ptr()->length_ = Smi::New(value); | |
| 9809 } | 9818 } |
| 9810 | 9819 |
| 9811 | 9820 |
| 9812 uword PcDescriptors::PC(intptr_t index) const { | 9821 uword PcDescriptors::PC(intptr_t index) const { |
| 9813 return static_cast<uword>(*(EntryAddr(index, kPcEntry))); | 9822 return static_cast<uword>(*(EntryAddr(index, kPcEntry))); |
| 9814 } | 9823 } |
| 9815 | 9824 |
| 9816 | 9825 |
| 9817 void PcDescriptors::SetPC(intptr_t index, uword value) const { | 9826 void PcDescriptors::SetPC(intptr_t index, uword value) const { |
| 9818 *(EntryAddr(index, kPcEntry)) = static_cast<intptr_t>(value); | 9827 *(EntryAddr(index, kPcEntry)) = static_cast<intptr_t>(value); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10000 uword PcDescriptors::GetPcForKind(Kind kind) const { | 10009 uword PcDescriptors::GetPcForKind(Kind kind) const { |
| 10001 for (intptr_t i = 0; i < Length(); i++) { | 10010 for (intptr_t i = 0; i < Length(); i++) { |
| 10002 if (DescriptorKind(i) == kind) { | 10011 if (DescriptorKind(i) == kind) { |
| 10003 return PC(i); | 10012 return PC(i); |
| 10004 } | 10013 } |
| 10005 } | 10014 } |
| 10006 return 0; | 10015 return 0; |
| 10007 } | 10016 } |
| 10008 | 10017 |
| 10009 | 10018 |
| 10010 void Stackmap::SetCode(const dart::Code& code) const { | |
| 10011 StorePointer(&raw_ptr()->code_, code.raw()); | |
| 10012 } | |
| 10013 | |
| 10014 | |
| 10015 bool Stackmap::GetBit(intptr_t bit_index) const { | 10019 bool Stackmap::GetBit(intptr_t bit_index) const { |
| 10016 ASSERT(InRange(bit_index)); | 10020 ASSERT(InRange(bit_index)); |
| 10017 int byte_index = bit_index >> kBitsPerByteLog2; | 10021 int byte_index = bit_index >> kBitsPerByteLog2; |
| 10018 int bit_remainder = bit_index & (kBitsPerByte - 1); | 10022 int bit_remainder = bit_index & (kBitsPerByte - 1); |
| 10019 uint8_t byte_mask = 1U << bit_remainder; | 10023 uint8_t byte_mask = 1U << bit_remainder; |
| 10020 uint8_t byte = raw_ptr()->data_[byte_index]; | 10024 uint8_t byte = raw_ptr()->data_[byte_index]; |
| 10021 return (byte & byte_mask); | 10025 return (byte & byte_mask); |
| 10022 } | 10026 } |
| 10023 | 10027 |
| 10024 | 10028 |
| (...skipping 8198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18223 return "_MirrorReference"; | 18227 return "_MirrorReference"; |
| 18224 } | 18228 } |
| 18225 | 18229 |
| 18226 | 18230 |
| 18227 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18231 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 18228 Instance::PrintToJSONStream(stream, ref); | 18232 Instance::PrintToJSONStream(stream, ref); |
| 18229 } | 18233 } |
| 18230 | 18234 |
| 18231 | 18235 |
| 18232 } // namespace dart | 18236 } // namespace dart |
| OLD | NEW |