Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: runtime/vm/object.cc

Issue 203523011: Introduce a lazy-compile stub for functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698