Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: runtime/vm/object.cc

Issue 380333002: Add VM class for Map/LinkedHashMap. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698