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

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: rewritten instruction pattern on ia32 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 if (PcDescriptors::Handle(current_code.pc_descriptors()).Length() == 0) {
3234 return;
3235 }
3236
3231 if (FLAG_trace_disabling_optimized_code) { 3237 if (FLAG_trace_disabling_optimized_code) {
3232 OS::Print("Disabling optimized code: '%s' entry: %#"Px"\n", 3238 OS::Print("Disabling optimized code: '%s' entry: %#"Px"\n",
3233 ToFullyQualifiedCString(), 3239 ToFullyQualifiedCString(),
3234 current_code.EntryPoint()); 3240 current_code.EntryPoint());
3235 } 3241 }
3236 // Patch entry of the optimized code. 3242 // Patch entry of the optimized code.
3237 CodePatcher::PatchEntry(current_code); 3243 CodePatcher::PatchEntry(current_code);
3238 // Use previously compiled unoptimized code. 3244 // Use previously compiled unoptimized code.
3239 SetCode(Code::Handle(unoptimized_code())); 3245 SetCode(Code::Handle(unoptimized_code()));
3240 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code())); 3246 CodePatcher::RestoreEntry(Code::Handle(unoptimized_code()));
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
4680 if (is_static) { 4686 if (is_static) {
4681 result.set_value(Instance::Handle()); 4687 result.set_value(Instance::Handle());
4682 } else { 4688 } else {
4683 result.SetOffset(0); 4689 result.SetOffset(0);
4684 } 4690 }
4685 result.set_is_final(is_final); 4691 result.set_is_final(is_final);
4686 result.set_is_const(is_const); 4692 result.set_is_const(is_const);
4687 result.set_owner(owner); 4693 result.set_owner(owner);
4688 result.set_token_pos(token_pos); 4694 result.set_token_pos(token_pos);
4689 result.set_has_initializer(false); 4695 result.set_has_initializer(false);
4696 result.set_guarded_cid(kIllegalCid);
4697 result.set_is_nullable(false);
4698 result.set_dependent_code(Array::Handle());
4690 return result.raw(); 4699 return result.raw();
4691 } 4700 }
4692 4701
4693 4702
4694 4703
4695 RawField* Field::Clone(const Class& new_owner) const { 4704 RawField* Field::Clone(const Class& new_owner) const {
4696 Field& clone = Field::Handle(); 4705 Field& clone = Field::Handle();
4697 clone ^= Object::Clone(*this, Heap::kOld); 4706 clone ^= Object::Clone(*this, Heap::kOld);
4698 const Class& owner = Class::Handle(this->owner()); 4707 const Class& owner = Class::Handle(this->owner());
4699 const PatchClass& clone_owner = 4708 const PatchClass& clone_owner =
4700 PatchClass::Handle(PatchClass::New(new_owner, owner)); 4709 PatchClass::Handle(PatchClass::New(new_owner, owner));
4701 clone.set_owner(clone_owner); 4710 clone.set_owner(clone_owner);
4711 clone.set_dependent_code(Array::Handle());
4702 if (!clone.is_static()) { 4712 if (!clone.is_static()) {
4703 clone.SetOffset(0); 4713 clone.SetOffset(0);
4704 } 4714 }
4705 return clone.raw(); 4715 return clone.raw();
4706 } 4716 }
4707 4717
4708 4718
4709 RawString* Field::UserVisibleName() const { 4719 RawString* Field::UserVisibleName() const {
4710 const String& str = String::Handle(name()); 4720 const String& str = String::Handle(name());
4711 return IdentifierPrettyName(str); 4721 return IdentifierPrettyName(str);
4712 } 4722 }
4713 4723
4714 4724
4715 const char* Field::ToCString() const { 4725 const char* Field::ToCString() const {
4716 const char* kF0 = is_static() ? " static" : ""; 4726 const char* kF0 = is_static() ? " static" : "";
4717 const char* kF1 = is_final() ? " final" : ""; 4727 const char* kF1 = is_final() ? " final" : "";
4718 const char* kF2 = is_const() ? " const" : ""; 4728 const char* kF2 = is_const() ? " const" : "";
4719 const char* kFormat = "Field <%s.%s>:%s%s%s"; 4729 const char* kFormat = "Field <%s.%s>:%s%s%s";
4720 const char* field_name = String::Handle(name()).ToCString(); 4730 const char* field_name = String::Handle(name()).ToCString();
4721 const Class& cls = Class::Handle(owner()); 4731 const Class& cls = Class::Handle(owner());
4722 const char* cls_name = String::Handle(cls.Name()).ToCString(); 4732 const char* cls_name = String::Handle(cls.Name()).ToCString();
4723 intptr_t len = 4733 intptr_t len =
4724 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; 4734 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1;
4725 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 4735 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
4726 OS::SNPrint(chars, len, kFormat, cls_name, field_name, kF0, kF1, kF2); 4736 OS::SNPrint(chars, len, kFormat, cls_name, field_name, kF0, kF1, kF2);
4727 return chars; 4737 return chars;
4728 } 4738 }
4729 4739
4730 4740
4741 RawArray* Field::dependent_code() const {
4742 return raw_ptr()->dependent_code_;
4743 }
4744
4745
4746 void Field::set_dependent_code(const Array& array) const {
4747 raw_ptr()->dependent_code_ = array.raw();
4748 }
4749
4750
4751 void Field::RegisterDependentCode(const Code& code) const {
4752 const Array& dependent = Array::Handle(dependent_code());
4753
4754 if (!dependent.IsNull()) {
4755 WeakProperty& weak_property = WeakProperty::Handle();
4756 for (intptr_t i = 0; i < dependent.Length(); i++) {
4757 weak_property ^= dependent.At(i);
4758 if (weak_property.key() == Code::null()) {
4759 weak_property.set_key(code);
4760 weak_property.set_value(code);
4761 return;
4762 }
4763 }
4764 }
4765
4766 const WeakProperty& weak_property = WeakProperty::Handle(
4767 WeakProperty::New(Heap::kOld));
4768 weak_property.set_key(code);
4769 weak_property.set_value(code);
4770
4771 intptr_t length = dependent.IsNull() ? 0 : dependent.Length();
4772 const Array& new_dependent = Array::Handle(
4773 Array::Grow(dependent, length + 1, Heap::kOld));
4774 new_dependent.SetAt(length, weak_property);
4775 set_dependent_code(new_dependent);
4776 }
4777
4778
4779 static bool ShouldDeoptimize(const Array& dependent_code, const Code& code) {
4780 if (!code.is_optimized()) {
4781 return false;
4782 }
4783
4784 WeakProperty& weak_property = WeakProperty::Handle();
4785 for (intptr_t i = 0; i < dependent_code.Length(); i++) {
4786 weak_property ^= dependent_code.At(i);
4787 if (code.raw() == weak_property.key()) {
4788 return true;
4789 }
4790 }
4791
4792 return false;
4793 }
4794
4795
4796 void Field::DeoptimizeDependentCode() const {
4797 const Array& code_objects = Array::Handle(dependent_code());
4798
4799 if (code_objects.IsNull()) {
4800 return;
4801 }
4802 set_dependent_code(Array::Handle());
4803
4804 // First deoptimize all dependent methods on the stack.
4805 Code& code = Code::Handle();
4806 {
4807 DartFrameIterator iterator;
4808 StackFrame* frame = iterator.NextFrame();
4809 while (frame != NULL) {
4810 code = frame->LookupDartCode();
4811 if (ShouldDeoptimize(code_objects, code)) {
4812 DeoptimizeAt(code, frame->pc());
4813 }
4814 frame = iterator.NextFrame();
4815 }
4816 }
4817
4818 WeakProperty& weak_property = WeakProperty::Handle();
4819 Function& function = Function::Handle();
4820 for (intptr_t i = 0; i < code_objects.Length(); i++) {
4821 weak_property ^= code_objects.At(i);
4822 code ^= weak_property.key();
4823 if (code.IsNull()) {
4824 continue;
4825 }
4826
4827 function ^= code.function();
4828 if (function.CurrentCode() == code.raw()) {
4829 ASSERT(function.HasOptimizedCode());
4830 function.SwitchToUnoptimizedCode();
4831 }
4832 }
4833 }
4834
4835
4836 void Field::UpdateCid(intptr_t cid) const {
4837 if (guarded_cid() == kIllegalCid) {
4838 set_guarded_cid(cid);
4839 set_is_nullable(cid == kNullCid);
4840 return;
4841 }
4842
4843 if ((cid == guarded_cid()) ||
4844 ((cid == kNullCid) && is_nullable())) {
4845 return;
4846 }
4847
4848 if ((cid == kNullCid) && !is_nullable()) {
4849 set_is_nullable(true);
4850 } else if ((cid != kNullCid) && (guarded_cid() == kNullCid)) {
4851 ASSERT(is_nullable());
4852 set_guarded_cid(cid);
4853 } else {
4854 ASSERT(guarded_cid() != cid);
4855 set_guarded_cid(kDynamicCid);
4856 set_is_nullable(true);
4857 }
4858
4859 DeoptimizeDependentCode();
4860 }
4861
4862
4731 void LiteralToken::set_literal(const String& literal) const { 4863 void LiteralToken::set_literal(const String& literal) const {
4732 StorePointer(&raw_ptr()->literal_, literal.raw()); 4864 StorePointer(&raw_ptr()->literal_, literal.raw());
4733 } 4865 }
4734 4866
4735 4867
4736 void LiteralToken::set_value(const Object& value) const { 4868 void LiteralToken::set_value(const Object& value) const {
4737 StorePointer(&raw_ptr()->value_, value.raw()); 4869 StorePointer(&raw_ptr()->value_, value.raw());
4738 } 4870 }
4739 4871
4740 4872
(...skipping 8656 matching lines...) Expand 10 before | Expand all | Expand 10 after
13397 } 13529 }
13398 return result.raw(); 13530 return result.raw();
13399 } 13531 }
13400 13532
13401 13533
13402 const char* WeakProperty::ToCString() const { 13534 const char* WeakProperty::ToCString() const {
13403 return "_WeakProperty"; 13535 return "_WeakProperty";
13404 } 13536 }
13405 13537
13406 } // namespace dart 13538 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698