Chromium Code Reviews| 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_patcher.h" | 12 #include "vm/code_patcher.h" |
| 13 #include "vm/compiler.h" | 13 #include "vm/compiler.h" |
| 14 #include "vm/compiler_stats.h" | 14 #include "vm/compiler_stats.h" |
| 15 #include "vm/class_finalizer.h" | 15 #include "vm/class_finalizer.h" |
| 16 #include "vm/dart.h" | 16 #include "vm/dart.h" |
| 17 #include "vm/dart_api_state.h" | 17 #include "vm/dart_api_state.h" |
| 18 #include "vm/dart_entry.h" | 18 #include "vm/dart_entry.h" |
| 19 #include "vm/debuginfo.h" | 19 #include "vm/debuginfo.h" |
| 20 #include "vm/disassembler.h" | |
| 20 #include "vm/double_conversion.h" | 21 #include "vm/double_conversion.h" |
| 21 #include "vm/exceptions.h" | 22 #include "vm/exceptions.h" |
| 22 #include "vm/growable_array.h" | 23 #include "vm/growable_array.h" |
| 23 #include "vm/heap.h" | 24 #include "vm/heap.h" |
| 24 #include "vm/object_store.h" | 25 #include "vm/object_store.h" |
| 25 #include "vm/parser.h" | 26 #include "vm/parser.h" |
| 26 #include "vm/runtime_entry.h" | 27 #include "vm/runtime_entry.h" |
| 27 #include "vm/scopes.h" | 28 #include "vm/scopes.h" |
| 28 #include "vm/stack_frame.h" | 29 #include "vm/stack_frame.h" |
| 29 #include "vm/timer.h" | 30 #include "vm/timer.h" |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); | 267 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); |
| 267 | 268 |
| 268 Class& cls = Class::Handle(); | 269 Class& cls = Class::Handle(); |
| 269 | 270 |
| 270 // Allocate and initialize the class class. | 271 // Allocate and initialize the class class. |
| 271 { | 272 { |
| 272 intptr_t size = Class::InstanceSize(); | 273 intptr_t size = Class::InstanceSize(); |
| 273 uword address = heap->Allocate(size, Heap::kOld); | 274 uword address = heap->Allocate(size, Heap::kOld); |
| 274 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); | 275 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); |
| 275 InitializeObject(address, Class::kInstanceKind, size); | 276 InitializeObject(address, Class::kInstanceKind, size); |
| 276 // Make the class_ field point to itself. | |
| 277 class_class_->ptr()->class_ = class_class_; | |
| 278 | 277 |
| 279 Class fake; | 278 Class fake; |
| 280 // Initialization from Class::New<Class>. | 279 // Initialization from Class::New<Class>. |
| 281 cls = class_class_; | 280 cls.ForceSetRaw(class_class_); |
| 282 cls.set_handle_vtable(fake.vtable()); | 281 cls.set_handle_vtable(fake.vtable()); |
| 283 cls.set_instance_size(Class::InstanceSize()); | 282 cls.set_instance_size(Class::InstanceSize()); |
| 284 cls.set_next_field_offset(Class::InstanceSize()); | 283 cls.set_next_field_offset(Class::InstanceSize()); |
| 285 cls.set_instance_kind(Class::kInstanceKind); | 284 cls.set_instance_kind(Class::kInstanceKind); |
| 286 cls.set_index(Class::kInstanceKind); | 285 cls.set_index(Class::kInstanceKind); |
| 287 cls.raw_ptr()->is_const_ = false; | 286 cls.raw_ptr()->is_const_ = false; |
| 288 cls.raw_ptr()->is_interface_ = false; | 287 cls.raw_ptr()->is_interface_ = false; |
| 289 cls.set_is_finalized(); | 288 cls.set_is_finalized(); |
| 290 cls.raw_ptr()->type_arguments_instance_field_offset_ = | 289 cls.raw_ptr()->type_arguments_instance_field_offset_ = |
| 291 Class::kNoTypeArguments; | 290 Class::kNoTypeArguments; |
| 292 cls.raw_ptr()->num_native_fields_ = 0; | 291 cls.raw_ptr()->num_native_fields_ = 0; |
| 293 cls.InitEmptyFields(); | 292 cls.InitEmptyFields(); |
| 294 Isolate::Current()->class_table()->Register(cls); | 293 Isolate::Current()->class_table()->Register(cls); |
| 295 } | 294 } |
| 296 | 295 |
| 297 // Allocate and initialize the null class. | 296 // Allocate and initialize the null class. |
| 298 cls = Class::New<Instance>(kNullClassIndex); | 297 cls = Class::New<Instance>(kNullClassIndex); |
| 299 cls.set_is_finalized(); | 298 cls.set_is_finalized(); |
| 300 null_class_ = cls.raw(); | 299 null_class_ = cls.raw(); |
| 301 | 300 |
| 302 // Complete initialization of null_ instance, i.e. initialize its class_ | |
| 303 // field. | |
| 304 null_->ptr()->class_ = null_class_; | |
| 305 | |
| 306 // Allocate and initialize the sentinel values of Null class. | 301 // Allocate and initialize the sentinel values of Null class. |
| 307 { | 302 { |
| 308 cls = null_class_; | 303 cls = null_class_; |
| 309 Instance& sentinel = Instance::Handle(); | 304 Instance& sentinel = Instance::Handle(); |
| 310 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 305 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| 311 sentinel_ = sentinel.raw(); | 306 sentinel_ = sentinel.raw(); |
| 312 | 307 |
| 313 Instance& transition_sentinel = Instance::Handle(); | 308 Instance& transition_sentinel = Instance::Handle(); |
| 314 transition_sentinel ^= | 309 transition_sentinel ^= |
| 315 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 310 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 if (address == 0) { | 976 if (address == 0) { |
| 982 // Use the preallocated out of memory exception to avoid calling | 977 // Use the preallocated out of memory exception to avoid calling |
| 983 // into dart code or allocating any code. | 978 // into dart code or allocating any code. |
| 984 const Instance& exception = | 979 const Instance& exception = |
| 985 Instance::Handle(isolate->object_store()->out_of_memory()); | 980 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 986 Exceptions::Throw(exception); | 981 Exceptions::Throw(exception); |
| 987 UNREACHABLE(); | 982 UNREACHABLE(); |
| 988 } | 983 } |
| 989 NoGCScope no_gc; | 984 NoGCScope no_gc; |
| 990 InitializeObject(address, cls.index(), size); | 985 InitializeObject(address, cls.index(), size); |
| 991 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 986 return reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 992 raw_obj->ptr()->class_ = cls.raw(); | |
| 993 ASSERT(cls.index() == RawObject::ClassTag::decode(raw_obj->ptr()->tags_)); | |
| 994 return raw_obj; | |
| 995 } | 987 } |
| 996 | 988 |
| 997 | 989 |
| 998 RawString* Class::Name() const { | 990 RawString* Class::Name() const { |
| 999 if (raw_ptr()->name_ != String::null()) { | 991 if (raw_ptr()->name_ != String::null()) { |
| 1000 return raw_ptr()->name_; | 992 return raw_ptr()->name_; |
| 1001 } | 993 } |
| 1002 ASSERT(class_class() != Class::null()); // class_class_ should be set up. | 994 ASSERT(class_class() != Class::null()); // class_class_ should be set up. |
| 1003 intptr_t index = GetSingletonClassIndex(raw()); | 995 intptr_t index = GetSingletonClassIndex(raw()); |
| 1004 return String::NewSymbol(GetSingletonClassName(index)); | 996 return String::NewSymbol(GetSingletonClassName(index)); |
| (...skipping 5290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6295 FindRawCodeVisitor visitor(pc); | 6287 FindRawCodeVisitor visitor(pc); |
| 6296 RawInstructions* instr; | 6288 RawInstructions* instr; |
| 6297 instr = isolate->heap()->FindObjectInCodeSpace(&visitor); | 6289 instr = isolate->heap()->FindObjectInCodeSpace(&visitor); |
| 6298 if (instr != Instructions::null()) { | 6290 if (instr != Instructions::null()) { |
| 6299 return instr->ptr()->code_; | 6291 return instr->ptr()->code_; |
| 6300 } | 6292 } |
| 6301 return Code::null(); | 6293 return Code::null(); |
| 6302 } | 6294 } |
| 6303 | 6295 |
| 6304 | 6296 |
| 6297 #ifdef DEBUG | |
| 6298 void Code::FindAndPrint(uword pc) { | |
|
Ivan Posva
2012/05/26 04:34:46
?
Vyacheslav Egorov (Google)
2012/05/26 16:48:22
This is a very useful helper method for debugging.
| |
| 6299 const Code& code = Code::Handle(Code::LookupCode(pc)); | |
| 6300 const Instructions& instructions = | |
| 6301 Instructions::Handle(code.instructions()); | |
| 6302 uword start = instructions.EntryPoint(); | |
| 6303 Disassembler::Disassemble(start, start + instructions.size()); | |
| 6304 } | |
| 6305 #endif | |
| 6306 | |
| 6307 | |
| 6305 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 6308 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
| 6306 intptr_t token_index = -1; | 6309 intptr_t token_index = -1; |
| 6307 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 6310 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 6308 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 6311 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
| 6309 if (descriptors.PC(i) == pc) { | 6312 if (descriptors.PC(i) == pc) { |
| 6310 token_index = descriptors.TokenIndex(i); | 6313 token_index = descriptors.TokenIndex(i); |
| 6311 break; | 6314 break; |
| 6312 } | 6315 } |
| 6313 } | 6316 } |
| 6314 return token_index; | 6317 return token_index; |
| (...skipping 2643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8958 return result.raw(); | 8961 return result.raw(); |
| 8959 } | 8962 } |
| 8960 | 8963 |
| 8961 | 8964 |
| 8962 void Array::MakeImmutable() const { | 8965 void Array::MakeImmutable() const { |
| 8963 Isolate* isolate = Isolate::Current(); | 8966 Isolate* isolate = Isolate::Current(); |
| 8964 const Class& cls = Class::Handle( | 8967 const Class& cls = Class::Handle( |
| 8965 isolate, isolate->object_store()->immutable_array_class()); | 8968 isolate, isolate->object_store()->immutable_array_class()); |
| 8966 { | 8969 { |
| 8967 NoGCScope no_gc; | 8970 NoGCScope no_gc; |
| 8968 raw_ptr()->class_ = cls.raw(); | |
| 8969 uword tags = raw_ptr()->tags_; | 8971 uword tags = raw_ptr()->tags_; |
| 8970 tags = RawObject::ClassTag::update(cls.index(), tags); | 8972 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 8971 raw_ptr()->tags_ = tags; | 8973 raw_ptr()->tags_ = tags; |
| 8972 } | 8974 } |
| 8973 } | 8975 } |
| 8974 | 8976 |
| 8975 | 8977 |
| 8976 const char* Array::ToCString() const { | 8978 const char* Array::ToCString() const { |
| 8977 return "Array"; | 8979 return "Array"; |
| 8978 } | 8980 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9029 if (capacity_size != used_size) { | 9031 if (capacity_size != used_size) { |
| 9030 ASSERT(capacity_len > used_len); | 9032 ASSERT(capacity_len > used_len); |
| 9031 intptr_t leftover_size = capacity_size - used_size; | 9033 intptr_t leftover_size = capacity_size - used_size; |
| 9032 | 9034 |
| 9033 uword addr = RawObject::ToAddr(array.raw()) + used_size; | 9035 uword addr = RawObject::ToAddr(array.raw()) + used_size; |
| 9034 if (leftover_size >= Array::InstanceSize(0)) { | 9036 if (leftover_size >= Array::InstanceSize(0)) { |
| 9035 // As we have enough space to use an array object, update the leftover | 9037 // As we have enough space to use an array object, update the leftover |
| 9036 // space as an Array object. | 9038 // space as an Array object. |
| 9037 RawArray* raw = reinterpret_cast<RawArray*>(RawObject::FromAddr(addr)); | 9039 RawArray* raw = reinterpret_cast<RawArray*>(RawObject::FromAddr(addr)); |
| 9038 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 9040 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
| 9039 raw->ptr()->class_ = cls.raw(); | |
| 9040 tags = 0; | 9041 tags = 0; |
| 9041 tags = RawObject::SizeTag::update(leftover_size, tags); | 9042 tags = RawObject::SizeTag::update(leftover_size, tags); |
| 9042 tags = RawObject::ClassTag::update(cls.index(), tags); | 9043 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 9043 raw->ptr()->tags_ = tags; | 9044 raw->ptr()->tags_ = tags; |
| 9044 intptr_t leftover_len = | 9045 intptr_t leftover_len = |
| 9045 ((leftover_size - Array::InstanceSize(0)) / kWordSize); | 9046 ((leftover_size - Array::InstanceSize(0)) / kWordSize); |
| 9046 raw->ptr()->tags_ = tags; | |
| 9047 raw->ptr()->length_ = Smi::New(leftover_len); | 9047 raw->ptr()->length_ = Smi::New(leftover_len); |
| 9048 } else { | 9048 } else { |
| 9049 // Update the leftover space as a basic object. | 9049 // Update the leftover space as a basic object. |
| 9050 ASSERT(leftover_size == Object::InstanceSize()); | 9050 ASSERT(leftover_size == Object::InstanceSize()); |
| 9051 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); | 9051 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); |
| 9052 const Class& cls = Class::Handle(isolate->object_store()->object_class()); | 9052 const Class& cls = Class::Handle(isolate->object_store()->object_class()); |
| 9053 raw->ptr()->class_ = cls.raw(); | |
| 9054 tags = 0; | 9053 tags = 0; |
| 9055 tags = RawObject::SizeTag::update(leftover_size, tags); | 9054 tags = RawObject::SizeTag::update(leftover_size, tags); |
| 9056 tags = RawObject::ClassTag::update(cls.index(), tags); | 9055 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 9057 raw->ptr()->tags_ = tags; | 9056 raw->ptr()->tags_ = tags; |
| 9058 } | 9057 } |
| 9059 } | 9058 } |
| 9060 return array.raw(); | 9059 return array.raw(); |
| 9061 } | 9060 } |
| 9062 | 9061 |
| 9063 | 9062 |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10042 const String& str = String::Handle(pattern()); | 10041 const String& str = String::Handle(pattern()); |
| 10043 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10042 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10044 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10043 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10045 char* chars = reinterpret_cast<char*>( | 10044 char* chars = reinterpret_cast<char*>( |
| 10046 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10045 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10047 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10046 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10048 return chars; | 10047 return chars; |
| 10049 } | 10048 } |
| 10050 | 10049 |
| 10051 } // namespace dart | 10050 } // namespace dart |
| OLD | NEW |