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

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

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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
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/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 3209 matching lines...) Expand 10 before | Expand all | Expand 10 after
3220 void Function::SetCode(const Code& value) const { 3220 void Function::SetCode(const Code& value) const {
3221 StorePointer(&raw_ptr()->code_, value.raw()); 3221 StorePointer(&raw_ptr()->code_, value.raw());
3222 ASSERT(Function::Handle(value.function()).IsNull() || 3222 ASSERT(Function::Handle(value.function()).IsNull() ||
3223 (value.function() == this->raw())); 3223 (value.function() == this->raw()));
3224 value.set_function(*this); 3224 value.set_function(*this);
3225 } 3225 }
3226 3226
3227 3227
3228 void Function::SwitchToUnoptimizedCode() const { 3228 void Function::SwitchToUnoptimizedCode() const {
3229 ASSERT(HasOptimizedCode()); 3229 ASSERT(HasOptimizedCode());
3230
3230 const Code& current_code = Code::Handle(CurrentCode()); 3231 const Code& current_code = Code::Handle(CurrentCode());
3232
3233 // Optimized code object might have been actually fully produced by the
3234 // intrinsifier in this case nothing has to be done. In fact an attempt to
3235 // patch such code will cause crash.
3236 // TODO(vegorov): if intrisifier can fully intrisify the function then we
3237 // should not later try to optimize it.
3238 if (PcDescriptors::Handle(current_code.pc_descriptors()).Length() == 0) {
3239 return;
3240 }
3241
3231 if (FLAG_trace_disabling_optimized_code) { 3242 if (FLAG_trace_disabling_optimized_code) {
3232 OS::Print("Disabling optimized code: '%s' entry: %#"Px"\n", 3243 OS::Print("Disabling optimized code: '%s' entry: %#"Px"\n",
3233 ToFullyQualifiedCString(), 3244 ToFullyQualifiedCString(),
3234 current_code.EntryPoint()); 3245 current_code.EntryPoint());
3235 } 3246 }
3236 // Patch entry of the optimized code. 3247 // Patch entry of the optimized code.
3237 CodePatcher::PatchEntry(current_code); 3248 CodePatcher::PatchEntry(current_code);
3238 // Use previously compiled unoptimized code. 3249 // Use previously compiled unoptimized code.
3239 SetCode(Code::Handle(unoptimized_code())); 3250 SetCode(Code::Handle(unoptimized_code()));
3240 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code())); 3251 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code()));
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
4680 if (is_static) { 4691 if (is_static) {
4681 result.set_value(Instance::Handle()); 4692 result.set_value(Instance::Handle());
4682 } else { 4693 } else {
4683 result.SetOffset(0); 4694 result.SetOffset(0);
4684 } 4695 }
4685 result.set_is_final(is_final); 4696 result.set_is_final(is_final);
4686 result.set_is_const(is_const); 4697 result.set_is_const(is_const);
4687 result.set_owner(owner); 4698 result.set_owner(owner);
4688 result.set_token_pos(token_pos); 4699 result.set_token_pos(token_pos);
4689 result.set_has_initializer(false); 4700 result.set_has_initializer(false);
4701 result.set_guarded_cid(kIllegalCid);
4702 result.set_is_nullable(false);
4703 result.set_dependent_code(Array::Handle());
4690 return result.raw(); 4704 return result.raw();
4691 } 4705 }
4692 4706
4693 4707
4694 4708
4695 RawField* Field::Clone(const Class& new_owner) const { 4709 RawField* Field::Clone(const Class& new_owner) const {
4696 Field& clone = Field::Handle(); 4710 Field& clone = Field::Handle();
4697 clone ^= Object::Clone(*this, Heap::kOld); 4711 clone ^= Object::Clone(*this, Heap::kOld);
4698 const Class& owner = Class::Handle(this->owner()); 4712 const Class& owner = Class::Handle(this->owner());
4699 const PatchClass& clone_owner = 4713 const PatchClass& clone_owner =
4700 PatchClass::Handle(PatchClass::New(new_owner, owner)); 4714 PatchClass::Handle(PatchClass::New(new_owner, owner));
4701 clone.set_owner(clone_owner); 4715 clone.set_owner(clone_owner);
4716 clone.set_dependent_code(Array::Handle());
4702 if (!clone.is_static()) { 4717 if (!clone.is_static()) {
4703 clone.SetOffset(0); 4718 clone.SetOffset(0);
4704 } 4719 }
4705 return clone.raw(); 4720 return clone.raw();
4706 } 4721 }
4707 4722
4708 4723
4709 RawString* Field::UserVisibleName() const { 4724 RawString* Field::UserVisibleName() const {
4710 const String& str = String::Handle(name()); 4725 const String& str = String::Handle(name());
4711 return IdentifierPrettyName(str); 4726 return IdentifierPrettyName(str);
4712 } 4727 }
4713 4728
4714 4729
4715 const char* Field::ToCString() const { 4730 const char* Field::ToCString() const {
4716 const char* kF0 = is_static() ? " static" : ""; 4731 const char* kF0 = is_static() ? " static" : "";
4717 const char* kF1 = is_final() ? " final" : ""; 4732 const char* kF1 = is_final() ? " final" : "";
4718 const char* kF2 = is_const() ? " const" : ""; 4733 const char* kF2 = is_const() ? " const" : "";
4719 const char* kFormat = "Field <%s.%s>:%s%s%s"; 4734 const char* kFormat = "Field <%s.%s>:%s%s%s";
4720 const char* field_name = String::Handle(name()).ToCString(); 4735 const char* field_name = String::Handle(name()).ToCString();
4721 const Class& cls = Class::Handle(owner()); 4736 const Class& cls = Class::Handle(owner());
4722 const char* cls_name = String::Handle(cls.Name()).ToCString(); 4737 const char* cls_name = String::Handle(cls.Name()).ToCString();
4723 intptr_t len = 4738 intptr_t len =
4724 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; 4739 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1;
4725 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 4740 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
4726 OS::SNPrint(chars, len, kFormat, cls_name, field_name, kF0, kF1, kF2); 4741 OS::SNPrint(chars, len, kFormat, cls_name, field_name, kF0, kF1, kF2);
4727 return chars; 4742 return chars;
4728 } 4743 }
4729 4744
4730 4745
4746 RawArray* Field::dependent_code() const {
4747 return raw_ptr()->dependent_code_;
4748 }
4749
4750
4751 void Field::set_dependent_code(const Array& array) const {
4752 raw_ptr()->dependent_code_ = array.raw();
4753 }
4754
4755
4756 void Field::RegisterDependentCode(const Code& code) const {
4757 const Array& dependent = Array::Handle(dependent_code());
4758
4759 if (!dependent.IsNull()) {
Ivan Posva 2013/03/19 16:00:49 Please add a comment what is being done here. As f
Vyacheslav Egorov (Google) 2013/03/19 19:57:50 Right now it seems safe. Comment added.
4760 WeakProperty& weak_property = WeakProperty::Handle();
4761 for (intptr_t i = 0; i < dependent.Length(); i++) {
4762 weak_property ^= dependent.At(i);
4763 if (weak_property.key() == Code::null()) {
4764 weak_property.set_key(code);
4765 weak_property.set_value(code);
4766 return;
4767 }
4768 }
4769 }
4770
4771 const WeakProperty& weak_property = WeakProperty::Handle(
4772 WeakProperty::New(Heap::kOld));
4773 weak_property.set_key(code);
4774 weak_property.set_value(code);
Ivan Posva 2013/03/19 16:00:49 Please explain why both key and value are set to c
Vyacheslav Egorov (Google) 2013/03/19 19:57:50 Yes, key would be enough. I just wanted to fill bo
4775
4776 intptr_t length = dependent.IsNull() ? 0 : dependent.Length();
4777 const Array& new_dependent = Array::Handle(
4778 Array::Grow(dependent, length + 1, Heap::kOld));
4779 new_dependent.SetAt(length, weak_property);
4780 set_dependent_code(new_dependent);
4781 }
4782
4783
4784 static bool ShouldDeoptimize(const Array& dependent_code, const Code& code) {
Ivan Posva 2013/03/19 16:00:49 This is a bit awkwardly named. What it really does
Vyacheslav Egorov (Google) 2013/03/19 19:57:50 Done.
4785 if (!code.is_optimized()) {
4786 return false;
4787 }
4788
4789 WeakProperty& weak_property = WeakProperty::Handle();
4790 for (intptr_t i = 0; i < dependent_code.Length(); i++) {
4791 weak_property ^= dependent_code.At(i);
4792 if (code.raw() == weak_property.key()) {
4793 return true;
4794 }
4795 }
4796
4797 return false;
4798 }
4799
4800
4801 void Field::DeoptimizeDependentCode() const {
4802 const Array& code_objects = Array::Handle(dependent_code());
4803
4804 if (code_objects.IsNull()) {
4805 return;
4806 }
4807 set_dependent_code(Array::Handle());
4808
4809 // First deoptimize all dependent methods on the stack.
4810 Code& code = Code::Handle();
4811 {
4812 DartFrameIterator iterator;
4813 StackFrame* frame = iterator.NextFrame();
4814 while (frame != NULL) {
4815 code = frame->LookupDartCode();
4816 if (ShouldDeoptimize(code_objects, code)) {
4817 DeoptimizeAt(code, frame->pc());
4818 }
4819 frame = iterator.NextFrame();
4820 }
4821 }
4822
4823 WeakProperty& weak_property = WeakProperty::Handle();
Ivan Posva 2013/03/19 16:00:49 Please add comment what this does. As far as I und
Vyacheslav Egorov (Google) 2013/03/19 19:57:50 Done.
4824 Function& function = Function::Handle();
4825 for (intptr_t i = 0; i < code_objects.Length(); i++) {
4826 weak_property ^= code_objects.At(i);
4827 code ^= weak_property.key();
4828 if (code.IsNull()) {
4829 continue;
4830 }
4831
4832 function ^= code.function();
4833 if (function.CurrentCode() == code.raw()) {
4834 ASSERT(function.HasOptimizedCode());
4835 function.SwitchToUnoptimizedCode();
4836 }
4837 }
4838 }
4839
4840
4841 void Field::UpdateCid(intptr_t cid) const {
Ivan Posva 2013/03/19 16:00:49 Comment about the two fields being updated separat
Vyacheslav Egorov (Google) 2013/03/19 19:57:50 There is a comment in the header file. I added mor
4842 if (guarded_cid() == kIllegalCid) {
4843 set_guarded_cid(cid);
4844 set_is_nullable(cid == kNullCid);
4845 return;
4846 }
4847
4848 if ((cid == guarded_cid()) ||
4849 ((cid == kNullCid) && is_nullable())) {
4850 return;
4851 }
4852
4853 if ((cid == kNullCid) && !is_nullable()) {
4854 set_is_nullable(true);
4855 } else if ((cid != kNullCid) && (guarded_cid() == kNullCid)) {
4856 ASSERT(is_nullable());
4857 set_guarded_cid(cid);
4858 } else {
4859 ASSERT(guarded_cid() != cid);
4860 set_guarded_cid(kDynamicCid);
4861 set_is_nullable(true);
4862 }
4863
4864 DeoptimizeDependentCode();
4865 }
4866
4867
4731 void LiteralToken::set_literal(const String& literal) const { 4868 void LiteralToken::set_literal(const String& literal) const {
4732 StorePointer(&raw_ptr()->literal_, literal.raw()); 4869 StorePointer(&raw_ptr()->literal_, literal.raw());
4733 } 4870 }
4734 4871
4735 4872
4736 void LiteralToken::set_value(const Object& value) const { 4873 void LiteralToken::set_value(const Object& value) const {
4737 StorePointer(&raw_ptr()->value_, value.raw()); 4874 StorePointer(&raw_ptr()->value_, value.raw());
4738 } 4875 }
4739 4876
4740 4877
(...skipping 8656 matching lines...) Expand 10 before | Expand all | Expand 10 after
13397 } 13534 }
13398 return result.raw(); 13535 return result.raw();
13399 } 13536 }
13400 13537
13401 13538
13402 const char* WeakProperty::ToCString() const { 13539 const char* WeakProperty::ToCString() const {
13403 return "_WeakProperty"; 13540 return "_WeakProperty";
13404 } 13541 }
13405 13542
13406 } // namespace dart 13543 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698