| 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" |
| 11 #include "vm/code_generator.h" | 11 #include "vm/code_generator.h" |
| 12 #include "vm/code_index_table.h" | 12 #include "vm/code_index_table.h" |
| 13 #include "vm/code_patcher.h" | 13 #include "vm/code_patcher.h" |
| 14 #include "vm/compiler.h" | 14 #include "vm/compiler.h" |
| 15 #include "vm/compiler_stats.h" | 15 #include "vm/compiler_stats.h" |
| 16 #include "vm/class_finalizer.h" | 16 #include "vm/class_finalizer.h" |
| 17 #include "vm/dart.h" | 17 #include "vm/dart.h" |
| 18 #include "vm/dart_api_state.h" | 18 #include "vm/dart_api_state.h" |
| 19 #include "vm/dart_entry.h" | 19 #include "vm/dart_entry.h" |
| 20 #include "vm/debuginfo.h" | 20 #include "vm/debuginfo.h" |
| 21 #include "vm/exceptions.h" | 21 #include "vm/exceptions.h" |
| 22 #include "vm/growable_array.h" | 22 #include "vm/growable_array.h" |
| 23 #include "vm/heap.h" | 23 #include "vm/heap.h" |
| 24 #include "vm/ic_data.h" | |
| 25 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| 26 #include "vm/parser.h" | 25 #include "vm/parser.h" |
| 27 #include "vm/runtime_entry.h" | 26 #include "vm/runtime_entry.h" |
| 28 #include "vm/scopes.h" | 27 #include "vm/scopes.h" |
| 29 #include "vm/timer.h" | 28 #include "vm/timer.h" |
| 30 #include "vm/unicode.h" | 29 #include "vm/unicode.h" |
| 31 | 30 |
| 32 namespace dart { | 31 namespace dart { |
| 33 | 32 |
| 34 DEFINE_FLAG(bool, generate_gdb_symbols, false, | 33 DEFINE_FLAG(bool, generate_gdb_symbols, false, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 reinterpret_cast<RawClass*>(RAW_NULL); | 79 reinterpret_cast<RawClass*>(RAW_NULL); |
| 81 RawClass* Object::exception_handlers_class_ = | 80 RawClass* Object::exception_handlers_class_ = |
| 82 reinterpret_cast<RawClass*>(RAW_NULL); | 81 reinterpret_cast<RawClass*>(RAW_NULL); |
| 83 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 82 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 84 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 83 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 85 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 84 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 86 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 85 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 87 RawClass* Object::unhandled_exception_class_ = | 86 RawClass* Object::unhandled_exception_class_ = |
| 88 reinterpret_cast<RawClass*>(RAW_NULL); | 87 reinterpret_cast<RawClass*>(RAW_NULL); |
| 89 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 88 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 89 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 90 #undef RAW_NULL | 90 #undef RAW_NULL |
| 91 | 91 |
| 92 int Object::GetSingletonClassIndex(const RawClass* raw_class) { | 92 int Object::GetSingletonClassIndex(const RawClass* raw_class) { |
| 93 ASSERT(raw_class->IsHeapObject()); | 93 ASSERT(raw_class->IsHeapObject()); |
| 94 if (raw_class == class_class()) { | 94 if (raw_class == class_class()) { |
| 95 return kClassClass; | 95 return kClassClass; |
| 96 } else if (raw_class == null_class()) { | 96 } else if (raw_class == null_class()) { |
| 97 return kNullClass; | 97 return kNullClass; |
| 98 } else if (raw_class == dynamic_class()) { | 98 } else if (raw_class == dynamic_class()) { |
| 99 return kDynamicClass; | 99 return kDynamicClass; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } else if (raw_class == context_scope_class()) { | 140 } else if (raw_class == context_scope_class()) { |
| 141 return kContextScopeClass; | 141 return kContextScopeClass; |
| 142 } else if (raw_class == api_error_class()) { | 142 } else if (raw_class == api_error_class()) { |
| 143 return kApiErrorClass; | 143 return kApiErrorClass; |
| 144 } else if (raw_class == language_error_class()) { | 144 } else if (raw_class == language_error_class()) { |
| 145 return kLanguageErrorClass; | 145 return kLanguageErrorClass; |
| 146 } else if (raw_class == unhandled_exception_class()) { | 146 } else if (raw_class == unhandled_exception_class()) { |
| 147 return kUnhandledExceptionClass; | 147 return kUnhandledExceptionClass; |
| 148 } else if (raw_class == unwind_error_class()) { | 148 } else if (raw_class == unwind_error_class()) { |
| 149 return kUnwindErrorClass; | 149 return kUnwindErrorClass; |
| 150 } else if (raw_class == icdata_class()) { |
| 151 return kICDataClass; |
| 150 } | 152 } |
| 151 return kInvalidIndex; | 153 return kInvalidIndex; |
| 152 } | 154 } |
| 153 | 155 |
| 154 | 156 |
| 155 RawClass* Object::GetSingletonClass(int index) { | 157 RawClass* Object::GetSingletonClass(int index) { |
| 156 switch (index) { | 158 switch (index) { |
| 157 case kClassClass: return class_class(); | 159 case kClassClass: return class_class(); |
| 158 case kNullClass: return null_class(); | 160 case kNullClass: return null_class(); |
| 159 case kDynamicClass: return dynamic_class(); | 161 case kDynamicClass: return dynamic_class(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 176 case kInstructionsClass: return instructions_class(); | 178 case kInstructionsClass: return instructions_class(); |
| 177 case kPcDescriptorsClass: return pc_descriptors_class(); | 179 case kPcDescriptorsClass: return pc_descriptors_class(); |
| 178 case kLocalVarDescriptorsClass: return var_descriptors_class(); | 180 case kLocalVarDescriptorsClass: return var_descriptors_class(); |
| 179 case kExceptionHandlersClass: return exception_handlers_class(); | 181 case kExceptionHandlersClass: return exception_handlers_class(); |
| 180 case kContextClass: return context_class(); | 182 case kContextClass: return context_class(); |
| 181 case kContextScopeClass: return context_scope_class(); | 183 case kContextScopeClass: return context_scope_class(); |
| 182 case kApiErrorClass: return api_error_class(); | 184 case kApiErrorClass: return api_error_class(); |
| 183 case kLanguageErrorClass: return language_error_class(); | 185 case kLanguageErrorClass: return language_error_class(); |
| 184 case kUnhandledExceptionClass: return unhandled_exception_class(); | 186 case kUnhandledExceptionClass: return unhandled_exception_class(); |
| 185 case kUnwindErrorClass: return unwind_error_class(); | 187 case kUnwindErrorClass: return unwind_error_class(); |
| 188 case kICDataClass: return icdata_class(); |
| 186 default: break; | 189 default: break; |
| 187 } | 190 } |
| 188 UNREACHABLE(); | 191 UNREACHABLE(); |
| 189 return reinterpret_cast<RawClass*>(kHeapObjectTag); // return RAW_NULL. | 192 return reinterpret_cast<RawClass*>(kHeapObjectTag); // return RAW_NULL. |
| 190 } | 193 } |
| 191 | 194 |
| 192 | 195 |
| 193 const char* Object::GetSingletonClassName(int index) { | 196 const char* Object::GetSingletonClassName(int index) { |
| 194 switch (index) { | 197 switch (index) { |
| 195 case kClassClass: return "Class"; | 198 case kClassClass: return "Class"; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 371 |
| 369 cls = Class::New<LanguageError>(); | 372 cls = Class::New<LanguageError>(); |
| 370 language_error_class_ = cls.raw(); | 373 language_error_class_ = cls.raw(); |
| 371 | 374 |
| 372 cls = Class::New<UnhandledException>(); | 375 cls = Class::New<UnhandledException>(); |
| 373 unhandled_exception_class_ = cls.raw(); | 376 unhandled_exception_class_ = cls.raw(); |
| 374 | 377 |
| 375 cls = Class::New<UnwindError>(); | 378 cls = Class::New<UnwindError>(); |
| 376 unwind_error_class_ = cls.raw(); | 379 unwind_error_class_ = cls.raw(); |
| 377 | 380 |
| 381 cls = Class::New<ICData>(); |
| 382 icdata_class_ = cls.raw(); |
| 383 |
| 378 ASSERT(class_class() != null_); | 384 ASSERT(class_class() != null_); |
| 379 } | 385 } |
| 380 | 386 |
| 381 | 387 |
| 382 RawClass* Object::CreateAndRegisterInterface(const char* cname, | 388 RawClass* Object::CreateAndRegisterInterface(const char* cname, |
| 383 const Script& script, | 389 const Script& script, |
| 384 const Library& lib) { | 390 const Library& lib) { |
| 385 const String& name = String::Handle(String::NewSymbol(cname)); | 391 const String& name = String::Handle(String::NewSymbol(cname)); |
| 386 const Class& cls = Class::Handle( | 392 const Class& cls = Class::Handle( |
| 387 Class::NewInterface(name, script, Scanner::kDummyTokenIndex)); | 393 Class::NewInterface(name, script, Scanner::kDummyTokenIndex)); |
| (...skipping 4819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5207 const Class& cls = Class::Handle(Object::code_class()); | 5213 const Class& cls = Class::Handle(Object::code_class()); |
| 5208 Code& result = Code::Handle(); | 5214 Code& result = Code::Handle(); |
| 5209 { | 5215 { |
| 5210 uword size = Code::InstanceSize(pointer_offsets_length); | 5216 uword size = Code::InstanceSize(pointer_offsets_length); |
| 5211 RawObject* raw = Object::Allocate(cls, size, Heap::kOld); | 5217 RawObject* raw = Object::Allocate(cls, size, Heap::kOld); |
| 5212 NoGCScope no_gc; | 5218 NoGCScope no_gc; |
| 5213 result ^= raw; | 5219 result ^= raw; |
| 5214 result.set_pointer_offsets_length(pointer_offsets_length); | 5220 result.set_pointer_offsets_length(pointer_offsets_length); |
| 5215 result.set_is_optimized(false); | 5221 result.set_is_optimized(false); |
| 5216 } | 5222 } |
| 5217 result.raw_ptr()->ic_data_ = Array::Empty(); | |
| 5218 return result.raw(); | 5223 return result.raw(); |
| 5219 } | 5224 } |
| 5220 | 5225 |
| 5221 | 5226 |
| 5222 RawCode* Code::FinalizeCode(const char* name, Assembler* assembler) { | 5227 RawCode* Code::FinalizeCode(const char* name, Assembler* assembler) { |
| 5223 ASSERT(assembler != NULL); | 5228 ASSERT(assembler != NULL); |
| 5224 | 5229 |
| 5225 // Allocate the Instructions object. | 5230 // Allocate the Instructions object. |
| 5226 Instructions& instrs = | 5231 Instructions& instrs = |
| 5227 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 5232 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5279 } | 5284 } |
| 5280 | 5285 |
| 5281 // Hook up Code and Instruction objects. | 5286 // Hook up Code and Instruction objects. |
| 5282 instrs.set_code(code.raw()); | 5287 instrs.set_code(code.raw()); |
| 5283 code.set_instructions(instrs.raw()); | 5288 code.set_instructions(instrs.raw()); |
| 5284 } | 5289 } |
| 5285 return code.raw(); | 5290 return code.raw(); |
| 5286 } | 5291 } |
| 5287 | 5292 |
| 5288 | 5293 |
| 5289 RawArray* Code::ic_data() const { | |
| 5290 return raw_ptr()->ic_data_; | |
| 5291 } | |
| 5292 | |
| 5293 | |
| 5294 void Code::set_ic_data(const Array& ic_data) const { | |
| 5295 ASSERT(!ic_data.IsNull()); | |
| 5296 StorePointer(&raw_ptr()->ic_data_, ic_data.raw()); | |
| 5297 } | |
| 5298 | |
| 5299 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 5294 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
| 5300 intptr_t token_index = -1; | 5295 intptr_t token_index = -1; |
| 5301 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 5296 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 5302 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 5297 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
| 5303 if (descriptors.PC(i) == pc) { | 5298 if (descriptors.PC(i) == pc) { |
| 5304 token_index = descriptors.TokenIndex(i); | 5299 token_index = descriptors.TokenIndex(i); |
| 5305 break; | 5300 break; |
| 5306 } | 5301 } |
| 5307 } | 5302 } |
| 5308 return token_index; | 5303 return token_index; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5348 if ((start_offset <= offset) && (offset < end_offset)) { | 5343 if ((start_offset <= offset) && (offset < end_offset)) { |
| 5349 return false; | 5344 return false; |
| 5350 } | 5345 } |
| 5351 } | 5346 } |
| 5352 return true; | 5347 return true; |
| 5353 } | 5348 } |
| 5354 | 5349 |
| 5355 | 5350 |
| 5356 void Code::ExtractIcDataArraysAtCalls( | 5351 void Code::ExtractIcDataArraysAtCalls( |
| 5357 GrowableArray<intptr_t>* node_ids, | 5352 GrowableArray<intptr_t>* node_ids, |
| 5358 GrowableArray<const Array*>* arrays) const { | 5353 GrowableArray<const ICData*>* ic_data_objs) const { |
| 5359 ASSERT(node_ids != NULL); | 5354 ASSERT(node_ids != NULL); |
| 5360 ASSERT(arrays != NULL); | 5355 ASSERT(ic_data_objs != NULL); |
| 5361 const PcDescriptors& descriptors = | 5356 const PcDescriptors& descriptors = |
| 5362 PcDescriptors::Handle(this->pc_descriptors()); | 5357 PcDescriptors::Handle(this->pc_descriptors()); |
| 5363 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 5358 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
| 5364 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { | 5359 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { |
| 5365 node_ids->Add(descriptors.NodeId(i)); | 5360 node_ids->Add(descriptors.NodeId(i)); |
| 5366 arrays->Add(&Array::ZoneHandle( | 5361 ic_data_objs->Add(&ICData::ZoneHandle( |
| 5367 CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)))); | 5362 CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)))); |
| 5368 } | 5363 } |
| 5369 } | 5364 } |
| 5370 } | 5365 } |
| 5371 | 5366 |
| 5372 | 5367 |
| 5373 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { | 5368 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { |
| 5374 ASSERT(num_variables >= 0); | 5369 ASSERT(num_variables >= 0); |
| 5375 | 5370 |
| 5376 const Class& context_class = Class::Handle(Object::context_class()); | 5371 const Class& context_class = Class::Handle(Object::context_class()); |
| (...skipping 2816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8193 const char* JSRegExp::ToCString() const { | 8188 const char* JSRegExp::ToCString() const { |
| 8194 const String& str = String::Handle(pattern()); | 8189 const String& str = String::Handle(pattern()); |
| 8195 const char* format = "JSRegExp: pattern=%s flags=%s"; | 8190 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 8196 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 8191 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 8197 char* chars = reinterpret_cast<char*>( | 8192 char* chars = reinterpret_cast<char*>( |
| 8198 Isolate::Current()->current_zone()->Allocate(len + 1)); | 8193 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 8199 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 8194 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 8200 return chars; | 8195 return chars; |
| 8201 } | 8196 } |
| 8202 | 8197 |
| 8198 |
| 8199 const char* ICData::ToCString() const { |
| 8200 return "ICData"; |
| 8201 } |
| 8202 |
| 8203 |
| 8204 void ICData::set_function(const Function& function) const { |
| 8205 raw_ptr()->function_ = function.raw(); |
| 8206 } |
| 8207 |
| 8208 |
| 8209 void ICData::set_target_name(const String& value) const { |
| 8210 raw_ptr()->target_name_ = value.raw(); |
| 8211 } |
| 8212 |
| 8213 |
| 8214 void ICData::set_id(intptr_t id) const { |
| 8215 raw_ptr()->id_ = id; |
| 8216 } |
| 8217 |
| 8218 |
| 8219 void ICData::set_num_args_tested(intptr_t num_args_tested) const { |
| 8220 raw_ptr()->num_args_tested_ = num_args_tested; |
| 8221 } |
| 8222 |
| 8223 |
| 8224 void ICData::set_ic_data(const Array& array) const { |
| 8225 raw_ptr()->ic_data_ = array.raw(); |
| 8226 } |
| 8227 |
| 8228 |
| 8229 intptr_t ICData::TestEntryLength() const { |
| 8230 return num_args_tested() + 1 /* target function*/; |
| 8231 } |
| 8232 |
| 8233 |
| 8234 intptr_t ICData::NumberOfChecks() const { |
| 8235 // Do not count the sentinel; |
| 8236 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; |
| 8237 } |
| 8238 |
| 8239 |
| 8240 void ICData::AddCheck(const GrowableArray<const Class*>& classes, |
| 8241 const Function& target) const { |
| 8242 ASSERT(classes.length() == num_args_tested()); |
| 8243 intptr_t old_num = NumberOfChecks(); |
| 8244 Array& data = Array::Handle(ic_data()); |
| 8245 intptr_t new_len = data.Length() + TestEntryLength(); |
| 8246 data = Array::Grow(data, new_len, Heap::kOld); |
| 8247 set_ic_data(data); |
| 8248 intptr_t data_pos = old_num * TestEntryLength(); |
| 8249 for (intptr_t i = 0; i < classes.length(); i++) { |
| 8250 // Null is used as terminating value, do not add it. |
| 8251 ASSERT(!classes[i]->IsNull()); |
| 8252 data.SetAt(data_pos++, *(classes[i])); |
| 8253 } |
| 8254 ASSERT(!target.IsNull()); |
| 8255 data.SetAt(data_pos, target); |
| 8256 } |
| 8257 |
| 8258 |
| 8259 void ICData::GetCheckAt(intptr_t index, |
| 8260 GrowableArray<const Class*>* classes, |
| 8261 Function* target) const { |
| 8262 ASSERT(classes != NULL); |
| 8263 ASSERT(target != NULL); |
| 8264 classes->Clear(); |
| 8265 const Array& data = Array::Handle(ic_data()); |
| 8266 intptr_t data_pos = index * TestEntryLength(); |
| 8267 for (intptr_t i = 0; i < num_args_tested(); i++) { |
| 8268 Class& cls = Class::ZoneHandle(); |
| 8269 cls ^= data.At(data_pos++); |
| 8270 classes->Add(&cls); |
| 8271 } |
| 8272 (*target) ^= data.At(data_pos); |
| 8273 } |
| 8274 |
| 8275 |
| 8276 void ICData::GetOneClassCheckAt( |
| 8277 int index, Class* cls, Function* target) const { |
| 8278 ASSERT(num_args_tested() == 1); |
| 8279 GrowableArray<const Class*> classes; |
| 8280 GetCheckAt(index, &classes, target); |
| 8281 *cls = classes[0]->raw(); |
| 8282 } |
| 8283 |
| 8284 |
| 8285 RawICData* ICData::New(const Function& function, |
| 8286 const String& target_name, |
| 8287 intptr_t id, |
| 8288 intptr_t num_args_tested) { |
| 8289 const Class& cls = Class::Handle(Object::icdata_class()); |
| 8290 ASSERT(!cls.IsNull()); |
| 8291 ICData& result = ICData::Handle(); |
| 8292 { |
| 8293 // IC data objects ar long living objects, allocate them in old generation. |
| 8294 RawObject* raw = |
| 8295 Object::Allocate(cls, ICData::InstanceSize(), Heap::kOld); |
| 8296 NoGCScope no_gc; |
| 8297 result ^= raw; |
| 8298 } |
| 8299 result.set_function(function); |
| 8300 result.set_target_name(target_name); |
| 8301 result.set_id(id); |
| 8302 result.set_num_args_tested(num_args_tested); |
| 8303 // Number of array elements in one test entry (num_args_tested + 1) |
| 8304 intptr_t len = num_args_tested + 1; |
| 8305 // IC data array must be null terminated (sentinel entry). |
| 8306 Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
| 8307 result.set_ic_data(ic_data); |
| 8308 return result.raw(); |
| 8309 } |
| 8310 |
| 8203 } // namespace dart | 8311 } // namespace dart |
| OLD | NEW |