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 "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" |
| 11 #include "vm/bigint_operations.h" | 11 #include "vm/bigint_operations.h" |
| 12 #include "vm/bit_vector.h" | |
| 12 #include "vm/bootstrap.h" | 13 #include "vm/bootstrap.h" |
| 13 #include "vm/class_finalizer.h" | 14 #include "vm/class_finalizer.h" |
| 14 #include "vm/code_generator.h" | 15 #include "vm/code_generator.h" |
| 15 #include "vm/code_observers.h" | 16 #include "vm/code_observers.h" |
| 16 #include "vm/code_patcher.h" | 17 #include "vm/code_patcher.h" |
| 17 #include "vm/compiler.h" | 18 #include "vm/compiler.h" |
| 18 #include "vm/compiler_stats.h" | 19 #include "vm/compiler_stats.h" |
| 19 #include "vm/dart.h" | 20 #include "vm/dart.h" |
| 20 #include "vm/dart_api_state.h" | 21 #include "vm/dart_api_state.h" |
| 21 #include "vm/dart_entry.h" | 22 #include "vm/dart_entry.h" |
| (...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1134 isolate->object_store()->set_bootstrap_library(ObjectStore::kMirrors, | 1135 isolate->object_store()->set_bootstrap_library(ObjectStore::kMirrors, |
| 1135 lib); | 1136 lib); |
| 1136 } | 1137 } |
| 1137 ASSERT(!lib.IsNull()); | 1138 ASSERT(!lib.IsNull()); |
| 1138 ASSERT(lib.raw() == Library::MirrorsLibrary()); | 1139 ASSERT(lib.raw() == Library::MirrorsLibrary()); |
| 1139 | 1140 |
| 1140 cls = Class::New<MirrorReference>(); | 1141 cls = Class::New<MirrorReference>(); |
| 1141 object_store->set_mirror_reference_class(cls); | 1142 object_store->set_mirror_reference_class(cls); |
| 1142 RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib); | 1143 RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib); |
| 1143 | 1144 |
| 1145 // Pre-register the profiler library so we can place the vm class | |
| 1146 // UserTag there rather than the core library. | |
| 1147 lib = Library::LookupLibrary(Symbols::DartProfiler()); | |
| 1148 if (lib.IsNull()) { | |
| 1149 lib = Library::NewLibraryHelper(Symbols::DartProfiler(), true); | |
| 1150 lib.Register(); | |
| 1151 isolate->object_store()->set_bootstrap_library(ObjectStore::kProfiler, | |
| 1152 lib); | |
| 1153 } | |
| 1154 ASSERT(!lib.IsNull()); | |
| 1155 ASSERT(lib.raw() == Library::ProfilerLibrary()); | |
| 1156 | |
| 1157 lib = Library::LookupLibrary(Symbols::DartProfiler()); | |
| 1158 ASSERT(!lib.IsNull()); | |
| 1159 cls = Class::New<UserTag>(); | |
| 1160 object_store->set_user_tag_class(cls); | |
| 1161 RegisterPrivateClass(cls, Symbols::_UserTag(), lib); | |
|
siva
2014/04/09 21:32:01
pending_classes.Add(cls) ?
Cutch
2014/04/09 22:27:20
Done.
| |
| 1162 | |
| 1163 cls = Class::New<Instance>(kIllegalCid); | |
| 1164 RegisterClass(cls, Symbols::UserTag(), lib); | |
| 1165 cls.set_num_type_arguments(0); | |
| 1166 cls.set_num_own_type_arguments(0); | |
| 1167 cls.set_is_prefinalized(); | |
| 1168 pending_classes.Add(cls); | |
|
siva
2014/04/09 21:32:01
Why do you have to initialize the UserTag class li
Cutch
2014/04/09 22:27:20
Done.
| |
| 1169 | |
| 1170 | |
| 1144 // Setup some default native field classes which can be extended for | 1171 // Setup some default native field classes which can be extended for |
| 1145 // specifying native fields in dart classes. | 1172 // specifying native fields in dart classes. |
| 1146 Library::InitNativeWrappersLibrary(isolate); | 1173 Library::InitNativeWrappersLibrary(isolate); |
| 1147 ASSERT(isolate->object_store()->native_wrappers_library() != Library::null()); | 1174 ASSERT(isolate->object_store()->native_wrappers_library() != Library::null()); |
| 1148 | 1175 |
| 1149 // Pre-register the typed_data library so the native class implementations | 1176 // Pre-register the typed_data library so the native class implementations |
| 1150 // can be hooked up before compiling it. | 1177 // can be hooked up before compiling it. |
| 1151 lib = Library::LookupLibrary(Symbols::DartTypedData()); | 1178 lib = Library::LookupLibrary(Symbols::DartTypedData()); |
| 1152 if (lib.IsNull()) { | 1179 if (lib.IsNull()) { |
| 1153 lib = Library::NewLibraryHelper(Symbols::DartTypedData(), true); | 1180 lib = Library::NewLibraryHelper(Symbols::DartTypedData(), true); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1432 // Some classes are not stored in the object store. Yet we still need to | 1459 // Some classes are not stored in the object store. Yet we still need to |
| 1433 // create their Class object so that they get put into the class_table | 1460 // create their Class object so that they get put into the class_table |
| 1434 // (as a side effect of Class::New()). | 1461 // (as a side effect of Class::New()). |
| 1435 cls = Class::New<Number>(); | 1462 cls = Class::New<Number>(); |
| 1436 | 1463 |
| 1437 cls = Class::New<WeakProperty>(); | 1464 cls = Class::New<WeakProperty>(); |
| 1438 object_store->set_weak_property_class(cls); | 1465 object_store->set_weak_property_class(cls); |
| 1439 | 1466 |
| 1440 cls = Class::New<MirrorReference>(); | 1467 cls = Class::New<MirrorReference>(); |
| 1441 object_store->set_mirror_reference_class(cls); | 1468 object_store->set_mirror_reference_class(cls); |
| 1469 | |
| 1470 cls = Class::New<UserTag>(); | |
| 1471 object_store->set_object_class(cls); | |
| 1442 } | 1472 } |
| 1443 | 1473 |
| 1444 | 1474 |
| 1445 void Object::Print() const { | 1475 void Object::Print() const { |
| 1446 OS::Print("%s\n", ToCString()); | 1476 OS::Print("%s\n", ToCString()); |
| 1447 } | 1477 } |
| 1448 | 1478 |
| 1449 | 1479 |
| 1450 RawString* Object::DictionaryName() const { | 1480 RawString* Object::DictionaryName() const { |
| 1451 return String::null(); | 1481 return String::null(); |
| (...skipping 7730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9182 RawLibrary* Library::NativeWrappersLibrary() { | 9212 RawLibrary* Library::NativeWrappersLibrary() { |
| 9183 return Isolate::Current()->object_store()->native_wrappers_library(); | 9213 return Isolate::Current()->object_store()->native_wrappers_library(); |
| 9184 } | 9214 } |
| 9185 | 9215 |
| 9186 | 9216 |
| 9187 RawLibrary* Library::TypedDataLibrary() { | 9217 RawLibrary* Library::TypedDataLibrary() { |
| 9188 return Isolate::Current()->object_store()->typed_data_library(); | 9218 return Isolate::Current()->object_store()->typed_data_library(); |
| 9189 } | 9219 } |
| 9190 | 9220 |
| 9191 | 9221 |
| 9222 RawLibrary* Library::ProfilerLibrary() { | |
| 9223 return Isolate::Current()->object_store()->profiler_library(); | |
| 9224 } | |
| 9225 | |
| 9226 | |
| 9192 const char* Library::ToCString() const { | 9227 const char* Library::ToCString() const { |
| 9193 const char* kFormat = "Library:'%s'"; | 9228 const char* kFormat = "Library:'%s'"; |
| 9194 const String& name = String::Handle(url()); | 9229 const String& name = String::Handle(url()); |
| 9195 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString()) + 1; | 9230 intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString()) + 1; |
| 9196 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 9231 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 9197 OS::SNPrint(chars, len, kFormat, name.ToCString()); | 9232 OS::SNPrint(chars, len, kFormat, name.ToCString()); |
| 9198 return chars; | 9233 return chars; |
| 9199 } | 9234 } |
| 9200 | 9235 |
| 9201 | 9236 |
| (...skipping 9057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18259 const char* MirrorReference::ToCString() const { | 18294 const char* MirrorReference::ToCString() const { |
| 18260 return "_MirrorReference"; | 18295 return "_MirrorReference"; |
| 18261 } | 18296 } |
| 18262 | 18297 |
| 18263 | 18298 |
| 18264 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18299 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 18265 Instance::PrintToJSONStream(stream, ref); | 18300 Instance::PrintToJSONStream(stream, ref); |
| 18266 } | 18301 } |
| 18267 | 18302 |
| 18268 | 18303 |
| 18304 void UserTag::MakeActive() const { | |
| 18305 Isolate* isolate = Isolate::Current(); | |
| 18306 ASSERT(isolate != NULL); | |
| 18307 intptr_t user_tag = tag(); | |
| 18308 isolate->set_user_tag(static_cast<uword>(user_tag)); | |
| 18309 isolate->object_store()->set_current_tag(*this); | |
|
siva
2014/04/09 21:32:01
should be isolate->set_current_tag();
Cutch
2014/04/09 22:27:20
Done.
| |
| 18310 } | |
| 18311 | |
| 18312 | |
| 18313 void UserTag::ClearActive() { | |
| 18314 Isolate* isolate = Isolate::Current(); | |
| 18315 ASSERT(isolate != NULL); | |
| 18316 isolate->set_user_tag(UserTags::kNoUserTag); | |
| 18317 isolate->object_store()->clear_current_tag(); | |
| 18318 } | |
| 18319 | |
| 18320 | |
| 18321 RawUserTag* UserTag::New(const String& label, Heap::Space space) { | |
| 18322 Isolate* isolate = Isolate::Current(); | |
| 18323 ASSERT(isolate->object_store()->user_tag_class() != Class::null()); | |
| 18324 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18325 // Canonicalize by name. | |
| 18326 UserTag& result = UserTag::Handle(FindTagInIsolate(isolate, label)); | |
| 18327 if (!result.IsNull()) { | |
| 18328 // Tag already exists, return existing instance. | |
| 18329 return result.raw(); | |
| 18330 } | |
| 18331 // No tag with label exists, create and register with isolate tag table. | |
| 18332 { | |
| 18333 RawObject* raw = Object::Allocate(UserTag::kClassId, | |
| 18334 UserTag::InstanceSize(), | |
| 18335 space); | |
| 18336 NoGCScope no_gc; | |
| 18337 result ^= raw; | |
| 18338 } | |
| 18339 result.set_label(label); | |
| 18340 intptr_t tag_id = FindAvailableTagId(isolate); | |
| 18341 ASSERT(tag_id >= 0); | |
| 18342 result.set_tag(tag_id); | |
| 18343 AddTagToIsolate(isolate, result); | |
| 18344 return result.raw(); | |
| 18345 } | |
| 18346 | |
| 18347 | |
| 18348 RawUserTag* UserTag::FindTagInIsolate(Isolate* isolate, const String& label) { | |
| 18349 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18350 const GrowableObjectArray& tag_table = GrowableObjectArray::Handle( | |
| 18351 isolate, isolate->object_store()->tag_table()); | |
|
siva
2014/04/09 21:32:01
Why is the tag table in the object store and not i
Cutch
2014/04/09 22:27:20
Moved to isolate.
| |
| 18352 UserTag& other = UserTag::Handle(isolate); | |
| 18353 String& tag_label = String::Handle(isolate); | |
| 18354 for (intptr_t i = 0; i < tag_table.Length(); i++) { | |
| 18355 other ^= tag_table.At(i); | |
| 18356 ASSERT(!other.IsNull()); | |
| 18357 tag_label ^= other.label(); | |
| 18358 ASSERT(!tag_label.IsNull()); | |
| 18359 if (tag_label.Equals(label)) { | |
| 18360 return other.raw(); | |
| 18361 } | |
| 18362 } | |
| 18363 return UserTag::null(); | |
| 18364 } | |
| 18365 | |
| 18366 | |
| 18367 void UserTag::AddTagToIsolate(Isolate* isolate, const UserTag& tag) { | |
| 18368 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18369 const GrowableObjectArray& tag_table = GrowableObjectArray::Handle( | |
| 18370 isolate, isolate->object_store()->tag_table()); | |
| 18371 #if defined(DEBUG) | |
| 18372 // Verify that no existing tag has the same tag id. | |
| 18373 UserTag& other = UserTag::Handle(isolate); | |
| 18374 for (intptr_t i = 0; i < tag_table.Length(); i++) { | |
| 18375 other ^= tag_table.At(i); | |
| 18376 ASSERT(!other.IsNull()); | |
| 18377 ASSERT(tag.tag() != other.tag()); | |
| 18378 } | |
| 18379 #endif | |
|
siva
2014/04/09 21:32:01
We should asert here that TagTableIsFull(isolate)
Cutch
2014/04/09 22:27:20
Done.
| |
| 18380 tag_table.Add(tag); | |
| 18381 } | |
| 18382 | |
| 18383 | |
| 18384 bool UserTag::TagTableIsFull(Isolate* isolate) { | |
| 18385 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18386 const GrowableObjectArray& tag_table = GrowableObjectArray::Handle( | |
| 18387 isolate, isolate->object_store()->tag_table()); | |
| 18388 ASSERT(tag_table.Length() <= UserTags::kMaxUserTags); | |
| 18389 return tag_table.Length() == UserTags::kMaxUserTags; | |
| 18390 } | |
| 18391 | |
| 18392 | |
| 18393 RawUserTag* UserTag::FindTagById(uword tag_id) { | |
| 18394 Isolate* isolate = Isolate::Current(); | |
| 18395 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18396 const GrowableObjectArray& tag_table = GrowableObjectArray::Handle( | |
| 18397 isolate, isolate->object_store()->tag_table()); | |
| 18398 UserTag& tag = UserTag::Handle(isolate); | |
| 18399 for (intptr_t i = 0; i < tag_table.Length(); i++) { | |
| 18400 tag ^= tag_table.At(i); | |
| 18401 if (tag.tag() == tag_id) { | |
| 18402 return tag.raw(); | |
| 18403 } | |
| 18404 } | |
|
siva
2014/04/09 21:32:01
If tag ids go sequentially this would just be an i
Cutch
2014/04/09 22:27:20
Done.
| |
| 18405 return UserTag::null(); | |
| 18406 } | |
| 18407 | |
| 18408 | |
| 18409 intptr_t UserTag::FindAvailableTagId(Isolate* isolate) { | |
| 18410 ASSERT(!TagTableIsFull(isolate)); | |
| 18411 ASSERT(isolate->object_store()->tag_table() != GrowableObjectArray::null()); | |
| 18412 const GrowableObjectArray& tag_table = GrowableObjectArray::Handle( | |
| 18413 isolate, isolate->object_store()->tag_table()); | |
| 18414 // Use a bit-vector to collect used tag ids. | |
| 18415 BitVector* bv = new BitVector(UserTags::kMaxUserTags); | |
| 18416 UserTag& other = UserTag::Handle(isolate); | |
| 18417 for (intptr_t i = 0; i < tag_table.Length(); i++) { | |
| 18418 other ^= tag_table.At(i); | |
| 18419 ASSERT(!other.IsNull()); | |
| 18420 ASSERT(other.tag() >= UserTags::kUserTagIdOffset); | |
| 18421 ASSERT(other.tag() < | |
| 18422 (UserTags::kUserTagIdOffset + UserTags::kMaxUserTags)); | |
| 18423 // Mark tag as used. | |
| 18424 bv->Add(other.tag() - UserTags::kUserTagIdOffset); | |
| 18425 } | |
| 18426 // Find first available id. | |
| 18427 for (intptr_t i = 0; i < bv->length(); i++) { | |
| 18428 if (!bv->Contains(i)) { | |
| 18429 return i + UserTags::kUserTagIdOffset; | |
| 18430 } | |
| 18431 } | |
|
siva
2014/04/09 21:32:01
As discussed offline, since you don't provide a me
Cutch
2014/04/09 22:27:20
Done.
| |
| 18432 // We should always be able to find an available tag id. | |
| 18433 UNREACHABLE(); | |
| 18434 return -1; | |
| 18435 } | |
| 18436 | |
| 18437 | |
| 18438 const char* UserTag::ToCString() const { | |
| 18439 const String& tag_label = String::Handle(label()); | |
| 18440 return tag_label.ToCString(); | |
| 18441 } | |
| 18442 | |
| 18443 | |
| 18444 void UserTag::PrintToJSONStream(JSONStream* stream, bool ref) const { | |
| 18445 Instance::PrintToJSONStream(stream, ref); | |
| 18446 } | |
| 18447 | |
| 18448 | |
| 18269 } // namespace dart | 18449 } // namespace dart |
| OLD | NEW |