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" |
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1146 lib.Register(); | 1146 lib.Register(); |
1147 isolate->object_store()->set_bootstrap_library(ObjectStore::kMirrors, | 1147 isolate->object_store()->set_bootstrap_library(ObjectStore::kMirrors, |
1148 lib); | 1148 lib); |
1149 } | 1149 } |
1150 ASSERT(!lib.IsNull()); | 1150 ASSERT(!lib.IsNull()); |
1151 ASSERT(lib.raw() == Library::MirrorsLibrary()); | 1151 ASSERT(lib.raw() == Library::MirrorsLibrary()); |
1152 | 1152 |
1153 cls = Class::New<MirrorReference>(); | 1153 cls = Class::New<MirrorReference>(); |
1154 RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib); | 1154 RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib); |
1155 | 1155 |
1156 // Pre-register the collection library so we can place the vm class | |
1157 // LinkedHashMap there rather than the core library. | |
1158 lib = Library::LookupLibrary(Symbols::DartCollection()); | |
1159 if (lib.IsNull()) { | |
1160 lib = Library::NewLibraryHelper(Symbols::DartCollection(), true); | |
1161 lib.SetLoadRequested(); | |
1162 lib.Register(); | |
1163 isolate->object_store()->set_bootstrap_library(ObjectStore::kCollection, | |
1164 lib); | |
1165 } | |
1166 ASSERT(!lib.IsNull()); | |
1167 ASSERT(lib.raw() == Library::CollectionLibrary()); | |
1168 | |
1169 cls = Class::New<LinkedHashMap>(); | |
1170 object_store->set_linked_hash_map_class(cls); | |
1171 cls.set_type_arguments_field_offset(LinkedHashMap::type_arguments_offset()); | |
1172 cls.set_num_type_arguments(2); | |
1173 cls.set_num_own_type_arguments(2); | |
1174 RegisterPrivateClass(cls, Symbols::_LinkedHashMap(), lib); | |
1175 pending_classes.Add(cls); | |
1176 | |
1156 // Pre-register the profiler library so we can place the vm class | 1177 // Pre-register the profiler library so we can place the vm class |
1157 // UserTag there rather than the core library. | 1178 // UserTag there rather than the core library. |
1158 lib = Library::LookupLibrary(Symbols::DartProfiler()); | 1179 lib = Library::LookupLibrary(Symbols::DartProfiler()); |
1159 if (lib.IsNull()) { | 1180 if (lib.IsNull()) { |
1160 lib = Library::NewLibraryHelper(Symbols::DartProfiler(), true); | 1181 lib = Library::NewLibraryHelper(Symbols::DartProfiler(), true); |
1161 lib.SetLoadRequested(); | 1182 lib.SetLoadRequested(); |
1162 lib.Register(); | 1183 lib.Register(); |
1163 isolate->object_store()->set_bootstrap_library(ObjectStore::kProfiler, | 1184 isolate->object_store()->set_bootstrap_library(ObjectStore::kProfiler, |
1164 lib); | 1185 lib); |
1165 } | 1186 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1416 | 1437 |
1417 cls = Class::New<Array>(); | 1438 cls = Class::New<Array>(); |
1418 object_store->set_array_class(cls); | 1439 object_store->set_array_class(cls); |
1419 | 1440 |
1420 cls = Class::New<Array>(kImmutableArrayCid); | 1441 cls = Class::New<Array>(kImmutableArrayCid); |
1421 object_store->set_immutable_array_class(cls); | 1442 object_store->set_immutable_array_class(cls); |
1422 | 1443 |
1423 cls = Class::New<GrowableObjectArray>(); | 1444 cls = Class::New<GrowableObjectArray>(); |
1424 object_store->set_growable_object_array_class(cls); | 1445 object_store->set_growable_object_array_class(cls); |
1425 | 1446 |
1447 cls = Class::New<LinkedHashMap>(); | |
1448 object_store->set_linked_hash_map_class(cls); | |
1449 | |
1426 cls = Class::New<Float32x4>(); | 1450 cls = Class::New<Float32x4>(); |
1427 object_store->set_float32x4_class(cls); | 1451 object_store->set_float32x4_class(cls); |
1428 | 1452 |
1429 cls = Class::New<Int32x4>(); | 1453 cls = Class::New<Int32x4>(); |
1430 object_store->set_int32x4_class(cls); | 1454 object_store->set_int32x4_class(cls); |
1431 | 1455 |
1432 cls = Class::New<Float64x2>(); | 1456 cls = Class::New<Float64x2>(); |
1433 object_store->set_float64x2_class(cls); | 1457 object_store->set_float64x2_class(cls); |
1434 | 1458 |
1435 #define REGISTER_TYPED_DATA_CLASS(clazz) \ | 1459 #define REGISTER_TYPED_DATA_CLASS(clazz) \ |
(...skipping 16546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17982 JSONObject jselement(&jsarr); | 18006 JSONObject jselement(&jsarr); |
17983 jselement.AddProperty("index", index); | 18007 jselement.AddProperty("index", index); |
17984 | 18008 |
17985 Object& element = Object::Handle(At(index)); | 18009 Object& element = Object::Handle(At(index)); |
17986 jselement.AddProperty("value", element); | 18010 jselement.AddProperty("value", element); |
17987 } | 18011 } |
17988 } | 18012 } |
17989 } | 18013 } |
17990 | 18014 |
17991 | 18015 |
18016 // Equivalent to Dart's operator "==" and hashCode. | |
18017 class DefaultHashTraits { | |
18018 public: | |
18019 static bool IsMatch(const Object& a, const Object& b) { | |
18020 if (a.IsNull() || b.IsNull()) { | |
siva
2014/07/23 22:43:07
why not
if (a.raw() == b.raw()) {
return true;
koda
2014/07/24 19:31:44
Because that could give the wrong result for NaN.
| |
18021 return (a.IsNull() && b.IsNull()); | |
18022 } else { | |
18023 return Instance::Cast(a).OperatorEquals(Instance::Cast(b)); | |
18024 } | |
18025 } | |
18026 static uword Hash(const Object& obj) { | |
18027 if (obj.IsNull()) { | |
18028 return 0; | |
18029 } | |
siva
2014/07/23 22:43:07
Need a NoGCScope here right as we have a raw objec
koda
2014/07/24 19:31:44
Although I don't think there was any actual bug, I
| |
18030 RawObject* raw_hash_code = Instance::Cast(obj).HashCode(); | |
18031 // TODO(koda): Ensure VM classes only produce Smi hash codes, and remove | |
18032 // non-Smi cases once Dart-side implementation is complete. | |
18033 if (raw_hash_code->IsHeapObject()) { | |
18034 Isolate* isolate = Isolate::Current(); | |
18035 REUSABLE_OBJECT_HANDLESCOPE(isolate); | |
18036 Object& hash_code = isolate->ObjectHandle(); | |
18037 hash_code = raw_hash_code; | |
18038 if (hash_code.IsInteger()) { | |
18039 return static_cast<uword>( | |
18040 Integer::Cast(hash_code).AsTruncatedUint32Value()); | |
18041 } else { | |
18042 return 0; | |
18043 } | |
18044 } else { | |
18045 // May waste some bits on 64-bit, to ensure consistency with non-Smi case. | |
18046 return static_cast<uword>( | |
18047 Smi::Value(Smi::RawCast(raw_hash_code)) & 0xFFFFFFFF); | |
18048 } | |
18049 } | |
18050 }; | |
18051 typedef EnumIndexHashMap<DefaultHashTraits> EnumIndexDefaultMap; | |
18052 | |
18053 | |
18054 intptr_t LinkedHashMap::Length() const { | |
18055 EnumIndexDefaultMap map(Array::Handle(data())); | |
18056 intptr_t result = map.NumOccupied(); | |
18057 { | |
18058 RawArray* array = map.Release(); | |
18059 ASSERT(array == data()); | |
18060 } | |
18061 return result; | |
18062 } | |
18063 | |
18064 | |
18065 void LinkedHashMap::InsertOrUpdate(const Object& key, | |
18066 const Object& value) const { | |
18067 ASSERT(!IsNull()); | |
18068 EnumIndexDefaultMap map(Array::Handle(data())); | |
18069 if (!map.UpdateOrInsert(key, value)) { | |
18070 SetModified(); | |
18071 } | |
18072 StorePointer(&raw_ptr()->data_, map.Release()); | |
18073 } | |
18074 | |
18075 | |
18076 RawObject* LinkedHashMap::LookUp(const Object& key) const { | |
18077 ASSERT(!IsNull()); | |
18078 EnumIndexDefaultMap map(Array::Handle(data())); | |
18079 Object& result = Object::Handle(map.GetOrNull(key)); | |
siva
2014/07/23 22:43:07
const Object& result ....
koda
2014/07/24 19:31:44
Done.
| |
18080 { | |
18081 RawArray* array = map.Release(); | |
18082 ASSERT(array == data()); | |
18083 } | |
18084 return result.raw(); | |
18085 } | |
18086 | |
18087 | |
18088 bool LinkedHashMap::Contains(const Object& key) const { | |
18089 ASSERT(!IsNull()); | |
18090 EnumIndexDefaultMap map(Array::Handle(data())); | |
18091 bool result = map.ContainsKey(key); | |
18092 { | |
18093 RawArray* array = map.Release(); | |
18094 ASSERT(array == data()); | |
18095 } | |
18096 return result; | |
18097 } | |
18098 | |
18099 | |
18100 RawObject* LinkedHashMap::Remove(const Object& key) const { | |
18101 ASSERT(!IsNull()); | |
18102 EnumIndexDefaultMap map(Array::Handle(data())); | |
18103 // TODO(koda): Make 'Remove' also return the old value. | |
18104 Object& result = Object::Handle(map.GetOrNull(key)); | |
siva
2014/07/23 22:43:06
const Object& result ....
koda
2014/07/24 19:31:44
Done.
| |
18105 if (map.Remove(key)) { | |
18106 SetModified(); | |
18107 } | |
18108 StorePointer(&raw_ptr()->data_, map.Release()); | |
18109 return result.raw(); | |
18110 } | |
18111 | |
18112 | |
18113 void LinkedHashMap::Clear() const { | |
18114 ASSERT(!IsNull()); | |
18115 if (Length() != 0) { | |
18116 SetModified(); | |
18117 } | |
18118 EnumIndexDefaultMap map(Array::Handle(data())); | |
18119 map.Initialize(); | |
18120 StorePointer(&raw_ptr()->data_, map.Release()); | |
siva
2014/07/23 22:43:07
Do we still require to do a map.Initialize() if Le
koda
2014/07/24 19:31:44
No, you are right. Moved everything into the 'if'.
| |
18121 } | |
18122 | |
18123 | |
18124 RawArray* LinkedHashMap::ToArray() const { | |
18125 EnumIndexDefaultMap map(Array::Handle(data())); | |
18126 const Array& result = Array::Handle(HashTables::ToArray(map, true)); | |
18127 RawArray* array = map.Release(); | |
18128 ASSERT(array == data()); | |
18129 return result.raw(); | |
18130 } | |
18131 | |
18132 | |
18133 void LinkedHashMap::SetModified() const { | |
18134 StorePointer(&raw_ptr()->cme_mark_, Instance::null()); | |
18135 } | |
18136 | |
18137 | |
18138 RawInstance* LinkedHashMap::GetModificationMark(bool create) const { | |
18139 if (create && raw_ptr()->cme_mark_ == Instance::null()) { | |
18140 Class& object_class = | |
18141 Class::Handle(Isolate::Current()->object_store()->object_class()); | |
18142 Instance& current = Instance::Handle(Instance::New(object_class)); | |
siva
2014/07/23 22:43:07
Would be worth allocating a local variable isolate
koda
2014/07/24 19:31:44
First part done.
As for the marks, we do need mor
| |
18143 StorePointer(&raw_ptr()->cme_mark_, current.raw()); | |
18144 } | |
18145 return raw_ptr()->cme_mark_; | |
18146 } | |
18147 | |
18148 | |
18149 RawLinkedHashMap* LinkedHashMap::New(Heap::Space space) { | |
18150 ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() | |
18151 != Class::null()); | |
18152 static const intptr_t kInitialCapacity = 4; | |
18153 const Array& data = | |
18154 Array::Handle(HashTables::New<EnumIndexDefaultMap>(kInitialCapacity, | |
18155 space)); | |
18156 LinkedHashMap& result = LinkedHashMap::Handle(); | |
18157 { | |
18158 RawObject* raw = Object::Allocate(LinkedHashMap::kClassId, | |
18159 LinkedHashMap::InstanceSize(), | |
18160 space); | |
18161 NoGCScope no_gc; | |
18162 result ^= raw; | |
18163 result.SetData(data); | |
18164 result.SetModified(); | |
18165 } | |
18166 return result.raw(); | |
18167 } | |
18168 | |
18169 | |
18170 const char* LinkedHashMap::ToCString() const { | |
18171 // TODO(koda): Print key/value pairs. | |
18172 return "_LinkedHashMap"; | |
18173 } | |
18174 | |
18175 | |
18176 void LinkedHashMap::PrintJSONImpl(JSONStream* stream, bool ref) const { | |
18177 // TODO(koda): Print key/value pairs. | |
18178 Instance::PrintJSONImpl(stream, ref); | |
18179 } | |
18180 | |
18181 | |
17992 RawFloat32x4* Float32x4::New(float v0, float v1, float v2, float v3, | 18182 RawFloat32x4* Float32x4::New(float v0, float v1, float v2, float v3, |
17993 Heap::Space space) { | 18183 Heap::Space space) { |
17994 ASSERT(Isolate::Current()->object_store()->float32x4_class() != | 18184 ASSERT(Isolate::Current()->object_store()->float32x4_class() != |
17995 Class::null()); | 18185 Class::null()); |
17996 Float32x4& result = Float32x4::Handle(); | 18186 Float32x4& result = Float32x4::Handle(); |
17997 { | 18187 { |
17998 RawObject* raw = Object::Allocate(Float32x4::kClassId, | 18188 RawObject* raw = Object::Allocate(Float32x4::kClassId, |
17999 Float32x4::InstanceSize(), | 18189 Float32x4::InstanceSize(), |
18000 space); | 18190 space); |
18001 NoGCScope no_gc; | 18191 NoGCScope no_gc; |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
19054 return tag_label.ToCString(); | 19244 return tag_label.ToCString(); |
19055 } | 19245 } |
19056 | 19246 |
19057 | 19247 |
19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19248 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
19059 Instance::PrintJSONImpl(stream, ref); | 19249 Instance::PrintJSONImpl(stream, ref); |
19060 } | 19250 } |
19061 | 19251 |
19062 | 19252 |
19063 } // namespace dart | 19253 } // namespace dart |
OLD | NEW |