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

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

Issue 20755004: Make sure that ICData always contains valid data (non-null values). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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') | no next file » | 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 8846 matching lines...) Expand 10 before | Expand all | Expand 10 after
8857 const intptr_t num_checks = NumberOfChecks(); 8857 const intptr_t num_checks = NumberOfChecks();
8858 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(), 8858 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(),
8859 num_args, num_checks) + 1; 8859 num_args, num_checks) + 1;
8860 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 8860 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
8861 OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks); 8861 OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks);
8862 return chars; 8862 return chars;
8863 } 8863 }
8864 8864
8865 8865
8866 void ICData::set_function(const Function& value) const { 8866 void ICData::set_function(const Function& value) const {
8867 ASSERT(!value.IsNull());
8867 StorePointer(&raw_ptr()->function_, value.raw()); 8868 StorePointer(&raw_ptr()->function_, value.raw());
8868 } 8869 }
8869 8870
8870 8871
8871 void ICData::set_target_name(const String& value) const { 8872 void ICData::set_target_name(const String& value) const {
8873 ASSERT(!value.IsNull());
8872 StorePointer(&raw_ptr()->target_name_, value.raw()); 8874 StorePointer(&raw_ptr()->target_name_, value.raw());
8873 } 8875 }
8874 8876
8875 8877
8876 void ICData::set_arguments_descriptor(const Array& value) const { 8878 void ICData::set_arguments_descriptor(const Array& value) const {
8879 ASSERT(!value.IsNull());
8877 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); 8880 StorePointer(&raw_ptr()->args_descriptor_, value.raw());
8878 } 8881 }
8879 8882
8880 void ICData::set_deopt_id(intptr_t value) const { 8883 void ICData::set_deopt_id(intptr_t value) const {
8881 raw_ptr()->deopt_id_ = value; 8884 raw_ptr()->deopt_id_ = value;
8882 } 8885 }
8883 8886
8884 8887
8885 void ICData::set_num_args_tested(intptr_t value) const { 8888 void ICData::set_num_args_tested(intptr_t value) const {
8886 raw_ptr()->num_args_tested_ = value; 8889 raw_ptr()->num_args_tested_ = value;
8887 } 8890 }
8888 8891
8889 8892
8890 void ICData::set_ic_data(const Array& value) const { 8893 void ICData::set_ic_data(const Array& value) const {
8894 ASSERT(!value.IsNull());
8891 StorePointer(&raw_ptr()->ic_data_, value.raw()); 8895 StorePointer(&raw_ptr()->ic_data_, value.raw());
8892 } 8896 }
8893 8897
8894 8898
8895 void ICData::set_deopt_reason(intptr_t deopt_reason) const { 8899 void ICData::set_deopt_reason(intptr_t deopt_reason) const {
8896 raw_ptr()->deopt_reason_ = deopt_reason; 8900 raw_ptr()->deopt_reason_ = deopt_reason;
8897 } 8901 }
8898 8902
8899 void ICData::set_is_closure_call(bool value) const { 8903 void ICData::set_is_closure_call(bool value) const {
8900 raw_ptr()->is_closure_call_ = value ? 1 : 0; 8904 raw_ptr()->is_closure_call_ = value ? 1 : 0;
(...skipping 10 matching lines...) Expand all
8911 } 8915 }
8912 8916
8913 8917
8914 intptr_t ICData::NumberOfChecks() const { 8918 intptr_t ICData::NumberOfChecks() const {
8915 // Do not count the sentinel; 8919 // Do not count the sentinel;
8916 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; 8920 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1;
8917 } 8921 }
8918 8922
8919 8923
8920 void ICData::WriteSentinel(const Array& data) const { 8924 void ICData::WriteSentinel(const Array& data) const {
8925 ASSERT(!data.IsNull());
8921 for (intptr_t i = 1; i <= TestEntryLength(); i++) { 8926 for (intptr_t i = 1; i <= TestEntryLength(); i++) {
8922 data.SetAt(data.Length() - i, smi_illegal_cid()); 8927 data.SetAt(data.Length() - i, smi_illegal_cid());
8923 } 8928 }
8924 } 8929 }
8925 8930
8926 8931
8927 #if defined(DEBUG) 8932 #if defined(DEBUG)
8928 // Used in asserts to verify that a check is not added twice. 8933 // Used in asserts to verify that a check is not added twice.
8929 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { 8934 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const {
8930 const intptr_t len = NumberOfChecks(); 8935 const intptr_t len = NumberOfChecks();
(...skipping 12 matching lines...) Expand all
8943 return true; 8948 return true;
8944 } 8949 }
8945 } 8950 }
8946 return false; 8951 return false;
8947 } 8952 }
8948 #endif // DEBUG 8953 #endif // DEBUG
8949 8954
8950 8955
8951 // Used for unoptimized static calls when no class-ids are checked. 8956 // Used for unoptimized static calls when no class-ids are checked.
8952 void ICData::AddTarget(const Function& target) const { 8957 void ICData::AddTarget(const Function& target) const {
8958 ASSERT(!target.IsNull());
8953 if (num_args_tested() > 0) { 8959 if (num_args_tested() > 0) {
8954 // Create a fake cid entry, so that we can store the target. 8960 // Create a fake cid entry, so that we can store the target.
8955 GrowableArray<intptr_t> class_ids(num_args_tested()); 8961 GrowableArray<intptr_t> class_ids(num_args_tested());
8956 for (intptr_t i = 0; i < num_args_tested(); i++) { 8962 for (intptr_t i = 0; i < num_args_tested(); i++) {
8957 class_ids.Add(kObjectCid); 8963 class_ids.Add(kObjectCid);
8958 } 8964 }
8959 AddCheck(class_ids, target); 8965 AddCheck(class_ids, target);
8960 return; 8966 return;
8961 } 8967 }
8962 ASSERT(num_args_tested() >= 0); 8968 ASSERT(num_args_tested() >= 0);
8963 // Can add only once. 8969 // Can add only once.
8964 const intptr_t old_num = NumberOfChecks(); 8970 const intptr_t old_num = NumberOfChecks();
8965 ASSERT(old_num == 0); 8971 ASSERT(old_num == 0);
8966 Array& data = Array::Handle(ic_data()); 8972 Array& data = Array::Handle(ic_data());
8967 const intptr_t new_len = data.Length() + TestEntryLength(); 8973 const intptr_t new_len = data.Length() + TestEntryLength();
8968 data = Array::Grow(data, new_len, Heap::kOld); 8974 data = Array::Grow(data, new_len, Heap::kOld);
8969 set_ic_data(data); 8975 set_ic_data(data);
8970 WriteSentinel(data); 8976 WriteSentinel(data);
8971 intptr_t data_pos = old_num * TestEntryLength(); 8977 intptr_t data_pos = old_num * TestEntryLength();
8972 ASSERT(!target.IsNull()); 8978 ASSERT(!target.IsNull());
8973 data.SetAt(data_pos++, target); 8979 data.SetAt(data_pos++, target);
8974 const Smi& value = Smi::Handle(Smi::New(0)); 8980 const Smi& value = Smi::Handle(Smi::New(0));
8975 data.SetAt(data_pos, value); 8981 data.SetAt(data_pos, value);
8976 } 8982 }
8977 8983
8978 8984
8979 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, 8985 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
8980 const Function& target) const { 8986 const Function& target) const {
8987 ASSERT(!target.IsNull());
8981 DEBUG_ASSERT(!HasCheck(class_ids)); 8988 DEBUG_ASSERT(!HasCheck(class_ids));
8982 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. 8989 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'.
8983 ASSERT(class_ids.length() == num_args_tested()); 8990 ASSERT(class_ids.length() == num_args_tested());
8984 const intptr_t old_num = NumberOfChecks(); 8991 const intptr_t old_num = NumberOfChecks();
8985 Array& data = Array::Handle(ic_data()); 8992 Array& data = Array::Handle(ic_data());
8986 // ICData of static calls with num_args_tested() > 0 have initially a 8993 // ICData of static calls with num_args_tested() > 0 have initially a
8987 // dummy set of cids entered (see ICData::AddTarget). That entry is 8994 // dummy set of cids entered (see ICData::AddTarget). That entry is
8988 // overwritten by first real type feedback data. 8995 // overwritten by first real type feedback data.
8989 if (old_num == 1) { 8996 if (old_num == 1) {
8990 bool has_dummy_entry = true; 8997 bool has_dummy_entry = true;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
9026 9033
9027 9034
9028 void ICData::AddReceiverCheck(intptr_t receiver_class_id, 9035 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
9029 const Function& target, 9036 const Function& target,
9030 intptr_t count) const { 9037 intptr_t count) const {
9031 #if defined(DEBUG) 9038 #if defined(DEBUG)
9032 GrowableArray<intptr_t> class_ids(1); 9039 GrowableArray<intptr_t> class_ids(1);
9033 class_ids.Add(receiver_class_id); 9040 class_ids.Add(receiver_class_id);
9034 ASSERT(!HasCheck(class_ids)); 9041 ASSERT(!HasCheck(class_ids));
9035 #endif // DEBUG 9042 #endif // DEBUG
9043 ASSERT(!target.IsNull());
9036 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. 9044 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'.
9037 ASSERT(receiver_class_id != kIllegalCid); 9045 ASSERT(receiver_class_id != kIllegalCid);
9038 9046
9039 const intptr_t old_num = NumberOfChecks(); 9047 const intptr_t old_num = NumberOfChecks();
9040 Array& data = Array::Handle(ic_data()); 9048 Array& data = Array::Handle(ic_data());
9041 const intptr_t new_len = data.Length() + TestEntryLength(); 9049 const intptr_t new_len = data.Length() + TestEntryLength();
9042 data = Array::Grow(data, new_len, Heap::kOld); 9050 data = Array::Grow(data, new_len, Heap::kOld);
9043 set_ic_data(data); 9051 set_ic_data(data);
9044 WriteSentinel(data); 9052 WriteSentinel(data);
9045 intptr_t data_pos = old_num * TestEntryLength(); 9053 intptr_t data_pos = old_num * TestEntryLength();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
9262 } 9270 }
9263 return true; 9271 return true;
9264 } 9272 }
9265 9273
9266 9274
9267 RawICData* ICData::New(const Function& function, 9275 RawICData* ICData::New(const Function& function,
9268 const String& target_name, 9276 const String& target_name,
9269 const Array& arguments_descriptor, 9277 const Array& arguments_descriptor,
9270 intptr_t deopt_id, 9278 intptr_t deopt_id,
9271 intptr_t num_args_tested) { 9279 intptr_t num_args_tested) {
9280 ASSERT(!function.IsNull());
9281 ASSERT(!target_name.IsNull());
9282 ASSERT(!arguments_descriptor.IsNull());
9272 ASSERT(Object::icdata_class() != Class::null()); 9283 ASSERT(Object::icdata_class() != Class::null());
9273 ASSERT(num_args_tested >= 0); 9284 ASSERT(num_args_tested >= 0);
9274 ICData& result = ICData::Handle(); 9285 ICData& result = ICData::Handle();
9275 { 9286 {
9276 // IC data objects are long living objects, allocate them in old generation. 9287 // IC data objects are long living objects, allocate them in old generation.
9277 RawObject* raw = Object::Allocate(ICData::kClassId, 9288 RawObject* raw = Object::Allocate(ICData::kClassId,
9278 ICData::InstanceSize(), 9289 ICData::InstanceSize(),
9279 Heap::kOld); 9290 Heap::kOld);
9280 NoGCScope no_gc; 9291 NoGCScope no_gc;
9281 result ^= raw; 9292 result ^= raw;
(...skipping 5086 matching lines...) Expand 10 before | Expand all | Expand 10 after
14368 } 14379 }
14369 14380
14370 14381
14371 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 14382 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
14372 stream->OpenObject(); 14383 stream->OpenObject();
14373 stream->CloseObject(); 14384 stream->CloseObject();
14374 } 14385 }
14375 14386
14376 14387
14377 } // namespace dart 14388 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698