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

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 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 for (intptr_t i = 0; i < dependent.Length(); i++) {
4756 if (dependent.At(i) == Code::null()) {
4757 dependent.SetAt(i, code);
4758 return;
4759 }
4760 }
4761 }
4762
4763 intptr_t length = dependent.IsNull() ? 0 : dependent.Length();
4764 const Array& new_dependent = Array::Handle(
4765 Array::Grow(dependent, length + 1, Heap::kOld));
4766 new_dependent.SetAt(length, code);
4767 set_dependent_code(new_dependent);
4768 }
4769
4770
4771 void Field::UnregisterDependentCode(const Code& code) const {
4772 const Array& dependent = Array::Handle(dependent_code());
4773 if (dependent.IsNull()) {
4774 return;
4775 }
4776
4777 intptr_t pos = 0;
4778 Code& dependent_code_object = Code::Handle();
4779 for (intptr_t i = 0; i < dependent.Length(); i++) {
4780 dependent_code_object ^= dependent.At(i);
4781 if (dependent_code_object.IsNull() ||
4782 (dependent_code_object.raw() == code.raw())) {
4783 continue;
4784 }
4785
4786 if (pos != i) {
4787 dependent.SetAt(pos++, dependent_code_object);
4788 }
4789 }
4790
4791 if (pos == 0) {
4792 set_dependent_code(Array::Handle());
4793 } else {
4794 Code& null_handle = Code::Handle();
4795 for (intptr_t i = pos; i < dependent.Length(); i++) {
4796 dependent.SetAt(i, null_handle);
4797 }
4798 }
4799 }
4800
4801
4802 static void UnregisterDependentCodeBeforeDeopt(const Code& code) {
4803 const Array& fields = Array::Handle(code.guarded_fields());
4804
4805 if (fields.IsNull()) {
4806 return;
4807 }
4808
4809 Field& field = Field::Handle();
4810 for (intptr_t i = 0; i < fields.Length(); i++) {
4811 field ^= fields.At(i);
4812 field.UnregisterDependentCode(code);
4813 }
4814
4815 code.set_guarded_fields(Array::Handle());
4816 }
4817
4818
4819 static bool ShouldDeoptimize(const Array& dependent_code, const Code& code) {
4820 if (!code.is_optimized()) {
4821 return false;
4822 }
4823
4824 for (intptr_t i = 0; i < dependent_code.Length(); i++) {
4825 if (code.raw() == dependent_code.At(i)) {
4826 return true;
4827 }
4828 }
4829
4830 return false;
4831 }
4832
4833
4834 void Field::DeoptimizeDependentCode() const {
4835 const Array& code_objects = Array::Handle(dependent_code());
4836
4837 if (code_objects.IsNull()) {
4838 return;
4839 }
4840 set_dependent_code(Array::Handle());
4841
4842 // First deoptimize all dependent methods on the stack.
4843 Code& code = Code::Handle();
4844 {
4845 DartFrameIterator iterator;
4846 StackFrame* frame = iterator.NextFrame();
4847 while (frame != NULL) {
4848 code = frame->LookupDartCode();
4849 if (ShouldDeoptimize(code_objects, code)) {
4850 UnregisterDependentCodeBeforeDeopt(code);
4851 DeoptimizeAt(code, frame->pc());
4852 }
4853 frame = iterator.NextFrame();
4854 }
4855 }
4856
4857 Function& function = Function::Handle();
4858 for (intptr_t i = 0; i < code_objects.Length(); i++) {
4859 code ^= code_objects.At(i);
4860 function ^= code.function();
4861 UnregisterDependentCodeBeforeDeopt(code);
4862 if (function.HasOptimizedCode()) {
4863 function.SwitchToUnoptimizedCode();
4864 }
4865 }
4866 }
4867
4868
4869 void Field::UpdateCid(intptr_t cid) const {
4870 if (guarded_cid() == kIllegalCid) {
4871 set_guarded_cid(cid);
4872 set_is_nullable(cid == kNullCid);
4873 return;
4874 }
4875
4876 if ((cid == guarded_cid()) ||
4877 ((cid == kNullCid) && is_nullable())) {
4878 return;
4879 }
4880
4881 if ((cid == kNullCid) && !is_nullable()) {
4882 set_is_nullable(true);
4883 } else if ((cid != kNullCid) && (guarded_cid() == kNullCid)) {
4884 ASSERT(is_nullable());
4885 set_guarded_cid(cid);
4886 } else {
4887 ASSERT(guarded_cid() != cid);
4888 set_guarded_cid(kDynamicCid);
4889 set_is_nullable(true);
4890 }
4891
4892 DeoptimizeDependentCode();
4893 }
4894
4895
4731 void LiteralToken::set_literal(const String& literal) const { 4896 void LiteralToken::set_literal(const String& literal) const {
4732 StorePointer(&raw_ptr()->literal_, literal.raw()); 4897 StorePointer(&raw_ptr()->literal_, literal.raw());
4733 } 4898 }
4734 4899
4735 4900
4736 void LiteralToken::set_value(const Object& value) const { 4901 void LiteralToken::set_value(const Object& value) const {
4737 StorePointer(&raw_ptr()->value_, value.raw()); 4902 StorePointer(&raw_ptr()->value_, value.raw());
4738 } 4903 }
4739 4904
4740 4905
(...skipping 2716 matching lines...) Expand 10 before | Expand all | Expand 10 after
7457 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); 7622 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_));
7458 return *comments; 7623 return *comments;
7459 } 7624 }
7460 7625
7461 7626
7462 void Code::set_comments(const Code::Comments& comments) const { 7627 void Code::set_comments(const Code::Comments& comments) const {
7463 StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); 7628 StorePointer(&raw_ptr()->comments_, comments.comments_.raw());
7464 } 7629 }
7465 7630
7466 7631
7632 RawArray* Code::guarded_fields() const {
7633 return raw_ptr()->guarded_fields_;
7634 }
7635
7636
7637 void Code::set_guarded_fields(const Array& guarded_fields) const {
7638 raw_ptr()->guarded_fields_ = guarded_fields.raw();
7639 }
7640
7641
7467 RawCode* Code::New(intptr_t pointer_offsets_length) { 7642 RawCode* Code::New(intptr_t pointer_offsets_length) {
7468 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { 7643 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) {
7469 // This should be caught before we reach here. 7644 // This should be caught before we reach here.
7470 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %"Pd"\n", 7645 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %"Pd"\n",
7471 pointer_offsets_length); 7646 pointer_offsets_length);
7472 } 7647 }
7473 ASSERT(Object::code_class() != Class::null()); 7648 ASSERT(Object::code_class() != Class::null());
7474 Code& result = Code::Handle(); 7649 Code& result = Code::Handle();
7475 { 7650 {
7476 uword size = Code::InstanceSize(pointer_offsets_length); 7651 uword size = Code::InstanceSize(pointer_offsets_length);
7477 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); 7652 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
7478 NoGCScope no_gc; 7653 NoGCScope no_gc;
7479 result ^= raw; 7654 result ^= raw;
7480 result.set_pointer_offsets_length(pointer_offsets_length); 7655 result.set_pointer_offsets_length(pointer_offsets_length);
7481 result.set_is_optimized(false); 7656 result.set_is_optimized(false);
7482 result.set_is_alive(true); 7657 result.set_is_alive(true);
7483 result.set_comments(Comments::New(0)); 7658 result.set_comments(Comments::New(0));
7659 result.set_guarded_fields(Array::Handle());
7484 } 7660 }
7485 return result.raw(); 7661 return result.raw();
7486 } 7662 }
7487 7663
7488 7664
7489 RawCode* Code::FinalizeCode(const char* name, 7665 RawCode* Code::FinalizeCode(const char* name,
7490 Assembler* assembler, 7666 Assembler* assembler,
7491 bool optimized) { 7667 bool optimized) {
7492 ASSERT(assembler != NULL); 7668 ASSERT(assembler != NULL);
7493 7669
(...skipping 5903 matching lines...) Expand 10 before | Expand all | Expand 10 after
13397 } 13573 }
13398 return result.raw(); 13574 return result.raw();
13399 } 13575 }
13400 13576
13401 13577
13402 const char* WeakProperty::ToCString() const { 13578 const char* WeakProperty::ToCString() const {
13403 return "_WeakProperty"; 13579 return "_WeakProperty";
13404 } 13580 }
13405 13581
13406 } // namespace dart 13582 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698