| OLD | NEW |
| 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 "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 RawClass* Object::library_prefix_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 78 RawClass* Object::library_prefix_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 79 RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 79 RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 80 RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 80 RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 81 RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 81 RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 82 RawClass* Object::var_descriptors_class_ = | 82 RawClass* Object::var_descriptors_class_ = |
| 83 reinterpret_cast<RawClass*>(RAW_NULL); | 83 reinterpret_cast<RawClass*>(RAW_NULL); |
| 84 RawClass* Object::exception_handlers_class_ = | 84 RawClass* Object::exception_handlers_class_ = |
| 85 reinterpret_cast<RawClass*>(RAW_NULL); | 85 reinterpret_cast<RawClass*>(RAW_NULL); |
| 86 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 86 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 87 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 87 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 88 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 88 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 89 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 89 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 90 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 90 RawClass* Object::unhandled_exception_class_ = | 91 RawClass* Object::unhandled_exception_class_ = |
| 91 reinterpret_cast<RawClass*>(RAW_NULL); | 92 reinterpret_cast<RawClass*>(RAW_NULL); |
| 92 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 93 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 93 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | |
| 94 #undef RAW_NULL | 94 #undef RAW_NULL |
| 95 | 95 |
| 96 int Object::GetSingletonClassIndex(const RawClass* raw_class) { | 96 int Object::GetSingletonClassIndex(const RawClass* raw_class) { |
| 97 ASSERT(raw_class->IsHeapObject()); | 97 ASSERT(raw_class->IsHeapObject()); |
| 98 if (raw_class == class_class()) { | 98 if (raw_class == class_class()) { |
| 99 return kClassClass; | 99 return kClassClass; |
| 100 } else if (raw_class == null_class()) { | 100 } else if (raw_class == null_class()) { |
| 101 return kNullClass; | 101 return kNullClass; |
| 102 } else if (raw_class == dynamic_class()) { | 102 } else if (raw_class == dynamic_class()) { |
| 103 return kDynamicClass; | 103 return kDynamicClass; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } else if (raw_class == pc_descriptors_class()) { | 138 } else if (raw_class == pc_descriptors_class()) { |
| 139 return kPcDescriptorsClass; | 139 return kPcDescriptorsClass; |
| 140 } else if (raw_class == var_descriptors_class()) { | 140 } else if (raw_class == var_descriptors_class()) { |
| 141 return kLocalVarDescriptorsClass; | 141 return kLocalVarDescriptorsClass; |
| 142 } else if (raw_class == exception_handlers_class()) { | 142 } else if (raw_class == exception_handlers_class()) { |
| 143 return kExceptionHandlersClass; | 143 return kExceptionHandlersClass; |
| 144 } else if (raw_class == context_class()) { | 144 } else if (raw_class == context_class()) { |
| 145 return kContextClass; | 145 return kContextClass; |
| 146 } else if (raw_class == context_scope_class()) { | 146 } else if (raw_class == context_scope_class()) { |
| 147 return kContextScopeClass; | 147 return kContextScopeClass; |
| 148 } else if (raw_class == icdata_class()) { |
| 149 return kICDataClass; |
| 148 } else if (raw_class == api_error_class()) { | 150 } else if (raw_class == api_error_class()) { |
| 149 return kApiErrorClass; | 151 return kApiErrorClass; |
| 150 } else if (raw_class == language_error_class()) { | 152 } else if (raw_class == language_error_class()) { |
| 151 return kLanguageErrorClass; | 153 return kLanguageErrorClass; |
| 152 } else if (raw_class == unhandled_exception_class()) { | 154 } else if (raw_class == unhandled_exception_class()) { |
| 153 return kUnhandledExceptionClass; | 155 return kUnhandledExceptionClass; |
| 154 } else if (raw_class == unwind_error_class()) { | 156 } else if (raw_class == unwind_error_class()) { |
| 155 return kUnwindErrorClass; | 157 return kUnwindErrorClass; |
| 156 } else if (raw_class == icdata_class()) { | |
| 157 return kICDataClass; | |
| 158 } | 158 } |
| 159 return kInvalidIndex; | 159 return kInvalidIndex; |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 RawClass* Object::GetSingletonClass(int index) { | 163 RawClass* Object::GetSingletonClass(int index) { |
| 164 switch (index) { | 164 switch (index) { |
| 165 case kClassClass: return class_class(); | 165 case kClassClass: return class_class(); |
| 166 case kNullClass: return null_class(); | 166 case kNullClass: return null_class(); |
| 167 case kDynamicClass: return dynamic_class(); | 167 case kDynamicClass: return dynamic_class(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 181 case kScriptClass: return script_class(); | 181 case kScriptClass: return script_class(); |
| 182 case kLibraryClass: return library_class(); | 182 case kLibraryClass: return library_class(); |
| 183 case kLibraryPrefixClass: return library_prefix_class(); | 183 case kLibraryPrefixClass: return library_prefix_class(); |
| 184 case kCodeClass: return code_class(); | 184 case kCodeClass: return code_class(); |
| 185 case kInstructionsClass: return instructions_class(); | 185 case kInstructionsClass: return instructions_class(); |
| 186 case kPcDescriptorsClass: return pc_descriptors_class(); | 186 case kPcDescriptorsClass: return pc_descriptors_class(); |
| 187 case kLocalVarDescriptorsClass: return var_descriptors_class(); | 187 case kLocalVarDescriptorsClass: return var_descriptors_class(); |
| 188 case kExceptionHandlersClass: return exception_handlers_class(); | 188 case kExceptionHandlersClass: return exception_handlers_class(); |
| 189 case kContextClass: return context_class(); | 189 case kContextClass: return context_class(); |
| 190 case kContextScopeClass: return context_scope_class(); | 190 case kContextScopeClass: return context_scope_class(); |
| 191 case kICDataClass: return icdata_class(); |
| 191 case kApiErrorClass: return api_error_class(); | 192 case kApiErrorClass: return api_error_class(); |
| 192 case kLanguageErrorClass: return language_error_class(); | 193 case kLanguageErrorClass: return language_error_class(); |
| 193 case kUnhandledExceptionClass: return unhandled_exception_class(); | 194 case kUnhandledExceptionClass: return unhandled_exception_class(); |
| 194 case kUnwindErrorClass: return unwind_error_class(); | 195 case kUnwindErrorClass: return unwind_error_class(); |
| 195 case kICDataClass: return icdata_class(); | |
| 196 default: break; | 196 default: break; |
| 197 } | 197 } |
| 198 UNREACHABLE(); | 198 UNREACHABLE(); |
| 199 return reinterpret_cast<RawClass*>(kHeapObjectTag); // return RAW_NULL. | 199 return reinterpret_cast<RawClass*>(kHeapObjectTag); // return RAW_NULL. |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 const char* Object::GetSingletonClassName(int index) { | 203 const char* Object::GetSingletonClassName(int index) { |
| 204 switch (index) { | 204 switch (index) { |
| 205 case kClassClass: return "Class"; | 205 case kClassClass: return "Class"; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 219 case kScriptClass: return "Script"; | 219 case kScriptClass: return "Script"; |
| 220 case kLibraryClass: return "Library"; | 220 case kLibraryClass: return "Library"; |
| 221 case kLibraryPrefixClass: return "LibraryPrefix"; | 221 case kLibraryPrefixClass: return "LibraryPrefix"; |
| 222 case kCodeClass: return "Code"; | 222 case kCodeClass: return "Code"; |
| 223 case kInstructionsClass: return "Instructions"; | 223 case kInstructionsClass: return "Instructions"; |
| 224 case kPcDescriptorsClass: return "PcDescriptors"; | 224 case kPcDescriptorsClass: return "PcDescriptors"; |
| 225 case kLocalVarDescriptorsClass: return "LocalVarDescriptors"; | 225 case kLocalVarDescriptorsClass: return "LocalVarDescriptors"; |
| 226 case kExceptionHandlersClass: return "ExceptionHandlers"; | 226 case kExceptionHandlersClass: return "ExceptionHandlers"; |
| 227 case kContextClass: return "Context"; | 227 case kContextClass: return "Context"; |
| 228 case kContextScopeClass: return "ContextScope"; | 228 case kContextScopeClass: return "ContextScope"; |
| 229 case kICDataClass: return "ICData"; |
| 229 case kApiErrorClass: return "ApiError"; | 230 case kApiErrorClass: return "ApiError"; |
| 230 case kLanguageErrorClass: return "LanguageError"; | 231 case kLanguageErrorClass: return "LanguageError"; |
| 231 case kUnhandledExceptionClass: return "UnhandledException"; | 232 case kUnhandledExceptionClass: return "UnhandledException"; |
| 232 case kUnwindErrorClass: return "UnwindError"; | 233 case kUnwindErrorClass: return "UnwindError"; |
| 233 default: break; | 234 default: break; |
| 234 } | 235 } |
| 235 UNREACHABLE(); | 236 UNREACHABLE(); |
| 236 return NULL; | 237 return NULL; |
| 237 } | 238 } |
| 238 | 239 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 | 370 |
| 370 cls = Class::New<ExceptionHandlers>(); | 371 cls = Class::New<ExceptionHandlers>(); |
| 371 exception_handlers_class_ = cls.raw(); | 372 exception_handlers_class_ = cls.raw(); |
| 372 | 373 |
| 373 cls = Class::New<Context>(); | 374 cls = Class::New<Context>(); |
| 374 context_class_ = cls.raw(); | 375 context_class_ = cls.raw(); |
| 375 | 376 |
| 376 cls = Class::New<ContextScope>(); | 377 cls = Class::New<ContextScope>(); |
| 377 context_scope_class_ = cls.raw(); | 378 context_scope_class_ = cls.raw(); |
| 378 | 379 |
| 380 cls = Class::New<ICData>(); |
| 381 icdata_class_ = cls.raw(); |
| 382 |
| 379 cls = Class::New<ApiError>(); | 383 cls = Class::New<ApiError>(); |
| 380 api_error_class_ = cls.raw(); | 384 api_error_class_ = cls.raw(); |
| 381 | 385 |
| 382 cls = Class::New<LanguageError>(); | 386 cls = Class::New<LanguageError>(); |
| 383 language_error_class_ = cls.raw(); | 387 language_error_class_ = cls.raw(); |
| 384 | 388 |
| 385 cls = Class::New<UnhandledException>(); | 389 cls = Class::New<UnhandledException>(); |
| 386 unhandled_exception_class_ = cls.raw(); | 390 unhandled_exception_class_ = cls.raw(); |
| 387 | 391 |
| 388 cls = Class::New<UnwindError>(); | 392 cls = Class::New<UnwindError>(); |
| 389 unwind_error_class_ = cls.raw(); | 393 unwind_error_class_ = cls.raw(); |
| 390 | 394 |
| 391 cls = Class::New<ICData>(); | |
| 392 icdata_class_ = cls.raw(); | |
| 393 | |
| 394 ASSERT(class_class() != null_); | 395 ASSERT(class_class() != null_); |
| 395 } | 396 } |
| 396 | 397 |
| 397 | 398 |
| 398 RawClass* Object::CreateAndRegisterInterface(const char* cname, | 399 RawClass* Object::CreateAndRegisterInterface(const char* cname, |
| 399 const Script& script, | 400 const Script& script, |
| 400 const Library& lib) { | 401 const Library& lib) { |
| 401 const String& name = String::Handle(String::NewSymbol(cname)); | 402 const String& name = String::Handle(String::NewSymbol(cname)); |
| 402 const Class& cls = Class::Handle( | 403 const Class& cls = Class::Handle( |
| 403 Class::NewInterface(name, script, Scanner::kDummyTokenIndex)); | 404 Class::NewInterface(name, script, Scanner::kDummyTokenIndex)); |
| (...skipping 5462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5866 intptr_t context_level) const { | 5867 intptr_t context_level) const { |
| 5867 VariableDescAddr(scope_index)->context_level = Smi::New(context_level); | 5868 VariableDescAddr(scope_index)->context_level = Smi::New(context_level); |
| 5868 } | 5869 } |
| 5869 | 5870 |
| 5870 | 5871 |
| 5871 const char* ContextScope::ToCString() const { | 5872 const char* ContextScope::ToCString() const { |
| 5872 return "ContextScope"; | 5873 return "ContextScope"; |
| 5873 } | 5874 } |
| 5874 | 5875 |
| 5875 | 5876 |
| 5877 const char* ICData::ToCString() const { |
| 5878 return "ICData"; |
| 5879 } |
| 5880 |
| 5881 |
| 5882 void ICData::set_function(const Function& value) const { |
| 5883 raw_ptr()->function_ = value.raw(); |
| 5884 } |
| 5885 |
| 5886 |
| 5887 void ICData::set_target_name(const String& value) const { |
| 5888 raw_ptr()->target_name_ = value.raw(); |
| 5889 } |
| 5890 |
| 5891 |
| 5892 void ICData::set_id(intptr_t value) const { |
| 5893 raw_ptr()->id_ = value; |
| 5894 } |
| 5895 |
| 5896 |
| 5897 void ICData::set_num_args_tested(intptr_t value) const { |
| 5898 raw_ptr()->num_args_tested_ = value; |
| 5899 } |
| 5900 |
| 5901 |
| 5902 void ICData::set_ic_data(const Array& value) const { |
| 5903 raw_ptr()->ic_data_ = value.raw(); |
| 5904 } |
| 5905 |
| 5906 |
| 5907 intptr_t ICData::TestEntryLength() const { |
| 5908 return num_args_tested() + 1 /* target function*/; |
| 5909 } |
| 5910 |
| 5911 |
| 5912 intptr_t ICData::NumberOfChecks() const { |
| 5913 // Do not count the sentinel; |
| 5914 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; |
| 5915 } |
| 5916 |
| 5917 |
| 5918 void ICData::AddCheck(const GrowableArray<const Class*>& classes, |
| 5919 const Function& target) const { |
| 5920 ASSERT(classes.length() == num_args_tested()); |
| 5921 intptr_t old_num = NumberOfChecks(); |
| 5922 Array& data = Array::Handle(ic_data()); |
| 5923 intptr_t new_len = data.Length() + TestEntryLength(); |
| 5924 data = Array::Grow(data, new_len, Heap::kOld); |
| 5925 set_ic_data(data); |
| 5926 intptr_t data_pos = old_num * TestEntryLength(); |
| 5927 for (intptr_t i = 0; i < classes.length(); i++) { |
| 5928 // Null is used as terminating value, do not add it. |
| 5929 ASSERT(!classes[i]->IsNull()); |
| 5930 data.SetAt(data_pos++, *(classes[i])); |
| 5931 } |
| 5932 ASSERT(!target.IsNull()); |
| 5933 data.SetAt(data_pos, target); |
| 5934 } |
| 5935 |
| 5936 |
| 5937 void ICData::GetCheckAt(intptr_t index, |
| 5938 GrowableArray<const Class*>* classes, |
| 5939 Function* target) const { |
| 5940 ASSERT(classes != NULL); |
| 5941 ASSERT(target != NULL); |
| 5942 classes->Clear(); |
| 5943 const Array& data = Array::Handle(ic_data()); |
| 5944 intptr_t data_pos = index * TestEntryLength(); |
| 5945 for (intptr_t i = 0; i < num_args_tested(); i++) { |
| 5946 Class& cls = Class::ZoneHandle(); |
| 5947 cls ^= data.At(data_pos++); |
| 5948 classes->Add(&cls); |
| 5949 } |
| 5950 (*target) ^= data.At(data_pos); |
| 5951 } |
| 5952 |
| 5953 |
| 5954 void ICData::GetOneClassCheckAt( |
| 5955 int index, Class* cls, Function* target) const { |
| 5956 ASSERT(cls != NULL); |
| 5957 ASSERT(target != NULL); |
| 5958 ASSERT(num_args_tested() == 1); |
| 5959 const Array& data = Array::Handle(ic_data()); |
| 5960 intptr_t data_pos = index * TestEntryLength(); |
| 5961 *cls ^= data.At(data_pos); |
| 5962 *target ^= data.At(data_pos + 1); |
| 5963 } |
| 5964 |
| 5965 |
| 5966 RawICData* ICData::New(const Function& function, |
| 5967 const String& target_name, |
| 5968 intptr_t id, |
| 5969 intptr_t num_args_tested) { |
| 5970 ASSERT(num_args_tested > 0); |
| 5971 const Class& cls = Class::Handle(Object::icdata_class()); |
| 5972 ASSERT(!cls.IsNull()); |
| 5973 ICData& result = ICData::Handle(); |
| 5974 { |
| 5975 // IC data objects ar long living objects, allocate them in old generation. |
| 5976 RawObject* raw = |
| 5977 Object::Allocate(cls, ICData::InstanceSize(), Heap::kOld); |
| 5978 NoGCScope no_gc; |
| 5979 result ^= raw; |
| 5980 } |
| 5981 result.set_function(function); |
| 5982 result.set_target_name(target_name); |
| 5983 result.set_id(id); |
| 5984 result.set_num_args_tested(num_args_tested); |
| 5985 // Number of array elements in one test entry (num_args_tested + 1) |
| 5986 intptr_t len = result.TestEntryLength(); |
| 5987 // IC data array must be null terminated (sentinel entry). |
| 5988 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
| 5989 result.set_ic_data(ic_data); |
| 5990 return result.raw(); |
| 5991 } |
| 5992 |
| 5993 |
| 5876 const char* Error::ToErrorCString() const { | 5994 const char* Error::ToErrorCString() const { |
| 5877 UNREACHABLE(); | 5995 UNREACHABLE(); |
| 5878 return "Internal Error"; | 5996 return "Internal Error"; |
| 5879 } | 5997 } |
| 5880 | 5998 |
| 5881 | 5999 |
| 5882 const char* Error::ToCString() const { | 6000 const char* Error::ToCString() const { |
| 5883 // Error is an abstract class. We should never reach here. | 6001 // Error is an abstract class. We should never reach here. |
| 5884 UNREACHABLE(); | 6002 UNREACHABLE(); |
| 5885 return "Error"; | 6003 return "Error"; |
| (...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8739 const char* JSRegExp::ToCString() const { | 8857 const char* JSRegExp::ToCString() const { |
| 8740 const String& str = String::Handle(pattern()); | 8858 const String& str = String::Handle(pattern()); |
| 8741 const char* format = "JSRegExp: pattern=%s flags=%s"; | 8859 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 8742 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 8860 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 8743 char* chars = reinterpret_cast<char*>( | 8861 char* chars = reinterpret_cast<char*>( |
| 8744 Isolate::Current()->current_zone()->Allocate(len + 1)); | 8862 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 8745 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 8863 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 8746 return chars; | 8864 return chars; |
| 8747 } | 8865 } |
| 8748 | 8866 |
| 8749 | |
| 8750 const char* ICData::ToCString() const { | |
| 8751 return "ICData"; | |
| 8752 } | |
| 8753 | |
| 8754 | |
| 8755 void ICData::set_function(const Function& value) const { | |
| 8756 raw_ptr()->function_ = value.raw(); | |
| 8757 } | |
| 8758 | |
| 8759 | |
| 8760 void ICData::set_target_name(const String& value) const { | |
| 8761 raw_ptr()->target_name_ = value.raw(); | |
| 8762 } | |
| 8763 | |
| 8764 | |
| 8765 void ICData::set_id(intptr_t value) const { | |
| 8766 raw_ptr()->id_ = value; | |
| 8767 } | |
| 8768 | |
| 8769 | |
| 8770 void ICData::set_num_args_tested(intptr_t value) const { | |
| 8771 raw_ptr()->num_args_tested_ = value; | |
| 8772 } | |
| 8773 | |
| 8774 | |
| 8775 void ICData::set_ic_data(const Array& value) const { | |
| 8776 raw_ptr()->ic_data_ = value.raw(); | |
| 8777 } | |
| 8778 | |
| 8779 | |
| 8780 intptr_t ICData::TestEntryLength() const { | |
| 8781 return num_args_tested() + 1 /* target function*/; | |
| 8782 } | |
| 8783 | |
| 8784 | |
| 8785 intptr_t ICData::NumberOfChecks() const { | |
| 8786 // Do not count the sentinel; | |
| 8787 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; | |
| 8788 } | |
| 8789 | |
| 8790 | |
| 8791 void ICData::AddCheck(const GrowableArray<const Class*>& classes, | |
| 8792 const Function& target) const { | |
| 8793 ASSERT(classes.length() == num_args_tested()); | |
| 8794 intptr_t old_num = NumberOfChecks(); | |
| 8795 Array& data = Array::Handle(ic_data()); | |
| 8796 intptr_t new_len = data.Length() + TestEntryLength(); | |
| 8797 data = Array::Grow(data, new_len, Heap::kOld); | |
| 8798 set_ic_data(data); | |
| 8799 intptr_t data_pos = old_num * TestEntryLength(); | |
| 8800 for (intptr_t i = 0; i < classes.length(); i++) { | |
| 8801 // Null is used as terminating value, do not add it. | |
| 8802 ASSERT(!classes[i]->IsNull()); | |
| 8803 data.SetAt(data_pos++, *(classes[i])); | |
| 8804 } | |
| 8805 ASSERT(!target.IsNull()); | |
| 8806 data.SetAt(data_pos, target); | |
| 8807 } | |
| 8808 | |
| 8809 | |
| 8810 void ICData::GetCheckAt(intptr_t index, | |
| 8811 GrowableArray<const Class*>* classes, | |
| 8812 Function* target) const { | |
| 8813 ASSERT(classes != NULL); | |
| 8814 ASSERT(target != NULL); | |
| 8815 classes->Clear(); | |
| 8816 const Array& data = Array::Handle(ic_data()); | |
| 8817 intptr_t data_pos = index * TestEntryLength(); | |
| 8818 for (intptr_t i = 0; i < num_args_tested(); i++) { | |
| 8819 Class& cls = Class::ZoneHandle(); | |
| 8820 cls ^= data.At(data_pos++); | |
| 8821 classes->Add(&cls); | |
| 8822 } | |
| 8823 (*target) ^= data.At(data_pos); | |
| 8824 } | |
| 8825 | |
| 8826 | |
| 8827 void ICData::GetOneClassCheckAt( | |
| 8828 int index, Class* cls, Function* target) const { | |
| 8829 ASSERT(cls != NULL); | |
| 8830 ASSERT(target != NULL); | |
| 8831 ASSERT(num_args_tested() == 1); | |
| 8832 const Array& data = Array::Handle(ic_data()); | |
| 8833 intptr_t data_pos = index * TestEntryLength(); | |
| 8834 *cls ^= data.At(data_pos); | |
| 8835 *target ^= data.At(data_pos + 1); | |
| 8836 } | |
| 8837 | |
| 8838 | |
| 8839 RawICData* ICData::New(const Function& function, | |
| 8840 const String& target_name, | |
| 8841 intptr_t id, | |
| 8842 intptr_t num_args_tested) { | |
| 8843 ASSERT(num_args_tested > 0); | |
| 8844 const Class& cls = Class::Handle(Object::icdata_class()); | |
| 8845 ASSERT(!cls.IsNull()); | |
| 8846 ICData& result = ICData::Handle(); | |
| 8847 { | |
| 8848 // IC data objects ar long living objects, allocate them in old generation. | |
| 8849 RawObject* raw = | |
| 8850 Object::Allocate(cls, ICData::InstanceSize(), Heap::kOld); | |
| 8851 NoGCScope no_gc; | |
| 8852 result ^= raw; | |
| 8853 } | |
| 8854 result.set_function(function); | |
| 8855 result.set_target_name(target_name); | |
| 8856 result.set_id(id); | |
| 8857 result.set_num_args_tested(num_args_tested); | |
| 8858 // Number of array elements in one test entry (num_args_tested + 1) | |
| 8859 intptr_t len = result.TestEntryLength(); | |
| 8860 // IC data array must be null terminated (sentinel entry). | |
| 8861 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | |
| 8862 result.set_ic_data(ic_data); | |
| 8863 return result.raw(); | |
| 8864 } | |
| 8865 | |
| 8866 } // namespace dart | 8867 } // namespace dart |
| OLD | NEW |