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

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

Issue 1666113002: Improve performance of Library::LookupLibrary(const String&). (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10145 matching lines...) Expand 10 before | Expand all | Expand 10 after
10156 ASSERT(Object::library_class() != Class::null()); 10156 ASSERT(Object::library_class() != Class::null());
10157 RawObject* raw = Object::Allocate(Library::kClassId, 10157 RawObject* raw = Object::Allocate(Library::kClassId,
10158 Library::InstanceSize(), 10158 Library::InstanceSize(),
10159 Heap::kOld); 10159 Heap::kOld);
10160 return reinterpret_cast<RawLibrary*>(raw); 10160 return reinterpret_cast<RawLibrary*>(raw);
10161 } 10161 }
10162 10162
10163 10163
10164 RawLibrary* Library::NewLibraryHelper(const String& url, 10164 RawLibrary* Library::NewLibraryHelper(const String& url,
10165 bool import_core_lib) { 10165 bool import_core_lib) {
10166 const Library& result = Library::Handle(Library::New()); 10166 const Library& result = Library::Handle(Library::New());
Ivan Posva 2016/02/05 04:53:54 You might want to ensure here that url has a hash
kasperl 2016/02/05 05:09:26 I do that when the library enters the library arra
10167 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw()); 10167 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
10168 result.StorePointer(&result.raw_ptr()->url_, url.raw()); 10168 result.StorePointer(&result.raw_ptr()->url_, url.raw());
10169 result.StorePointer(&result.raw_ptr()->resolved_names_, 10169 result.StorePointer(&result.raw_ptr()->resolved_names_,
10170 Object::empty_array().raw()); 10170 Object::empty_array().raw());
10171 result.StorePointer(&result.raw_ptr()->dictionary_, 10171 result.StorePointer(&result.raw_ptr()->dictionary_,
10172 Object::empty_array().raw()); 10172 Object::empty_array().raw());
10173 result.StorePointer(&result.raw_ptr()->metadata_, 10173 result.StorePointer(&result.raw_ptr()->metadata_,
10174 GrowableObjectArray::New(4, Heap::kOld)); 10174 GrowableObjectArray::New(4, Heap::kOld));
10175 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null()); 10175 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
10176 result.StorePointer(&result.raw_ptr()->patch_classes_, 10176 result.StorePointer(&result.raw_ptr()->patch_classes_,
10177 GrowableObjectArray::New(Object::empty_array(), 10177 GrowableObjectArray::New(Object::empty_array(),
10178 Heap::kOld)); 10178 Heap::kOld));
10179 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw()); 10179 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
10180 result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw()); 10180 result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
10181 result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null()); 10181 result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null());
10182 result.StorePointer(&result.raw_ptr()->load_error_, Instance::null()); 10182 result.StorePointer(&result.raw_ptr()->load_error_, Instance::null());
10183 result.set_native_entry_resolver(NULL); 10183 result.set_native_entry_resolver(NULL);
10184 result.set_native_entry_symbol_resolver(NULL); 10184 result.set_native_entry_symbol_resolver(NULL);
10185 result.set_is_in_fullsnapshot(false); 10185 result.set_is_in_fullsnapshot(false);
10186 result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true); 10186 result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true);
10187 result.set_debuggable(false); 10187 result.set_debuggable(false);
10188 result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme())); 10188 result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme()));
10189 result.StoreNonPointer(&result.raw_ptr()->load_state_, 10189 result.StoreNonPointer(&result.raw_ptr()->load_state_,
10190 RawLibrary::kAllocated); 10190 RawLibrary::kAllocated);
10191 result.StoreNonPointer(&result.raw_ptr()->index_, -1); 10191 result.StoreNonPointer(&result.raw_ptr()->index_, -1);
10192 const intptr_t kInitialNameCacheSize = 64; 10192 const intptr_t kInitialNameCacheSize = 64;
10193 result.InitResolvedNamesCache(kInitialNameCacheSize); 10193 result.InitResolvedNamesCache(kInitialNameCacheSize);
10194 result.InitClassDictionary(); 10194 result.InitClassDictionary();
10195 result.InitImportList(); 10195 result.InitImportList();
10196 result.AllocatePrivateKey(); 10196 result.AllocatePrivateKey();
kasperl 2016/02/05 05:09:26 The allocation of the private key (which is also l
10197 if (import_core_lib) { 10197 if (import_core_lib) {
10198 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 10198 const Library& core_lib = Library::Handle(Library::CoreLibrary());
10199 ASSERT(!core_lib.IsNull()); 10199 ASSERT(!core_lib.IsNull());
10200 const Namespace& ns = Namespace::Handle( 10200 const Namespace& ns = Namespace::Handle(
10201 Namespace::New(core_lib, Object::null_array(), Object::null_array())); 10201 Namespace::New(core_lib, Object::null_array(), Object::null_array()));
10202 result.AddImport(ns); 10202 result.AddImport(ns);
10203 } 10203 }
10204 return result.raw(); 10204 return result.raw();
10205 } 10205 }
10206 10206
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
10269 10269
10270 // Returns library with given url in current isolate, or NULL. 10270 // Returns library with given url in current isolate, or NULL.
10271 RawLibrary* Library::LookupLibrary(const String &url) { 10271 RawLibrary* Library::LookupLibrary(const String &url) {
10272 Thread* thread = Thread::Current(); 10272 Thread* thread = Thread::Current();
10273 Zone* zone = thread->zone(); 10273 Zone* zone = thread->zone();
10274 Isolate* isolate = thread->isolate(); 10274 Isolate* isolate = thread->isolate();
10275 Library& lib = Library::Handle(zone, Library::null()); 10275 Library& lib = Library::Handle(zone, Library::null());
10276 String& lib_url = String::Handle(zone, String::null()); 10276 String& lib_url = String::Handle(zone, String::null());
10277 GrowableObjectArray& libs = GrowableObjectArray::Handle( 10277 GrowableObjectArray& libs = GrowableObjectArray::Handle(
10278 zone, isolate->object_store()->libraries()); 10278 zone, isolate->object_store()->libraries());
10279 for (int i = 0; i < libs.Length(); i++) { 10279
10280 // Make sure the URL string has an associated hash code
10281 // to speed up the repeated equality checks.
10282 url.Hash();
Ivan Posva 2016/02/05 04:53:54 In the past we have had a negative performance imp
kasperl 2016/02/05 05:09:26 The url string will be compared using Equals to a
10283
10284 intptr_t len = libs.Length();
10285 for (intptr_t i = 0; i < len; i++) {
10280 lib ^= libs.At(i); 10286 lib ^= libs.At(i);
10281 lib_url ^= lib.url(); 10287 lib_url ^= lib.url();
10288
10289 ASSERT(url.HasHash() && lib_url.HasHash());
Ivan Posva 2016/02/05 04:53:54 How do you guarantee that lib_url has a hash code
kasperl 2016/02/05 05:09:25 It's hashed as part of NewLibraryHelper and I chec
Ivan Posva 2016/02/05 05:57:41 I was wondering about how the hash was being enfor
10282 if (lib_url.Equals(url)) { 10290 if (lib_url.Equals(url)) {
10283 return lib.raw(); 10291 return lib.raw();
10284 } 10292 }
10285 } 10293 }
10286 return Library::null(); 10294 return Library::null();
10287 } 10295 }
10288 10296
10289 10297
10290 RawError* Library::Patch(const Script& script) const { 10298 RawError* Library::Patch(const Script& script) const {
10291 ASSERT(script.kind() == RawScript::kPatchTag); 10299 ASSERT(script.kind() == RawScript::kPatchTag);
(...skipping 28 matching lines...) Expand all
10320 if (lib_key == key) { 10328 if (lib_key == key) {
10321 return true; 10329 return true;
10322 } 10330 }
10323 } 10331 }
10324 return false; 10332 return false;
10325 } 10333 }
10326 10334
10327 10335
10328 void Library::AllocatePrivateKey() const { 10336 void Library::AllocatePrivateKey() const {
10329 const String& url = String::Handle(this->url()); 10337 const String& url = String::Handle(this->url());
10330 intptr_t key_value = url.Hash() & kIntptrMax; 10338 intptr_t key_value = url.Hash() & kIntptrMax;
kasperl 2016/02/05 05:14:18 Here's the url.Hash() calll. I wonder why we canno
Ivan Posva 2016/02/05 05:57:42 Side note: We have discussed making the private ke
10331 while ((key_value == 0) || Library::IsKeyUsed(key_value)) { 10339 while ((key_value == 0) || Library::IsKeyUsed(key_value)) {
10332 key_value = (key_value + 1) & kIntptrMax; 10340 key_value = (key_value + 1) & kIntptrMax;
10333 } 10341 }
10334 ASSERT(key_value > 0); 10342 ASSERT(key_value > 0);
10335 char private_key[32]; 10343 char private_key[32];
10336 OS::SNPrint(private_key, sizeof(private_key), 10344 OS::SNPrint(private_key, sizeof(private_key),
10337 "%c%" Pd "", kPrivateKeySeparator, key_value); 10345 "%c%" Pd "", kPrivateKeySeparator, key_value);
10338 StorePointer(&raw_ptr()->private_key_, String::New(private_key, Heap::kOld)); 10346 StorePointer(&raw_ptr()->private_key_, String::New(private_key, Heap::kOld));
10339 } 10347 }
10340 10348
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
10378 Library& lib = Library::Handle(); 10386 Library& lib = Library::Handle();
10379 lib ^= libs.At(index); 10387 lib ^= libs.At(index);
10380 return lib.raw(); 10388 return lib.raw();
10381 } 10389 }
10382 return Library::null(); 10390 return Library::null();
10383 } 10391 }
10384 10392
10385 10393
10386 void Library::Register() const { 10394 void Library::Register() const {
10387 ASSERT(Library::LookupLibrary(String::Handle(url())) == Library::null()); 10395 ASSERT(Library::LookupLibrary(String::Handle(url())) == Library::null());
10396 ASSERT(String::Handle(url()).HasHash());
10388 ObjectStore* object_store = Isolate::Current()->object_store(); 10397 ObjectStore* object_store = Isolate::Current()->object_store();
10389 GrowableObjectArray& libs = 10398 GrowableObjectArray& libs =
10390 GrowableObjectArray::Handle(object_store->libraries()); 10399 GrowableObjectArray::Handle(object_store->libraries());
10391 ASSERT(!libs.IsNull()); 10400 ASSERT(!libs.IsNull());
10392 set_index(libs.Length()); 10401 set_index(libs.Length());
10393 libs.Add(*this); 10402 libs.Add(*this);
10394 } 10403 }
10395 10404
10396 10405
10397 RawLibrary* Library::AsyncLibrary() { 10406 RawLibrary* Library::AsyncLibrary() {
(...skipping 9184 matching lines...) Expand 10 before | Expand all | Expand 10 after
19582 return ExternalTwoByteString::GetPeer(*this); 19591 return ExternalTwoByteString::GetPeer(*this);
19583 } 19592 }
19584 19593
19585 19594
19586 bool String::Equals(const Instance& other) const { 19595 bool String::Equals(const Instance& other) const {
19587 if (this->raw() == other.raw()) { 19596 if (this->raw() == other.raw()) {
19588 // Both handles point to the same raw instance. 19597 // Both handles point to the same raw instance.
19589 return true; 19598 return true;
19590 } 19599 }
19591 19600
19592 if (!other.IsString() || other.IsNull()) { 19601 if (!other.IsString()) {
Ivan Posva 2016/02/05 04:53:54 This removal is not correct. String handles can st
kasperl 2016/02/05 05:09:25 If other.IsString() is true then it can flow throu
Ivan Posva 2016/02/05 05:57:41 Generally you are not supposed to XYZ:Cast() a nul
19593 return false; 19602 return false;
19594 } 19603 }
19595 19604
19596 const String& other_string = String::Cast(other); 19605 const String& other_string = String::Cast(other);
19597 if (this->HasHash() && other_string.HasHash() && 19606 return Equals(other_string);
19598 (this->Hash() != other_string.Hash())) {
19599 return false; // Both sides have a hash code and it does not match.
19600 }
19601 return Equals(other_string, 0, other_string.Length());
19602 } 19607 }
19603 19608
19604 19609
19610 bool String::Equals(const String& str,
19611 intptr_t begin_index,
19612 intptr_t len) const {
19613 ASSERT(begin_index >= 0);
19614 ASSERT((begin_index == 0) || (begin_index < str.Length()));
19615 ASSERT(len >= 0);
19616 ASSERT(len <= str.Length());
19617 if (len != this->Length()) {
19618 return false; // Lengths don't match.
19619 }
19620
19621 Scanner::CharAtFunc this_char_at_func = this->CharAtFunc();
19622 Scanner::CharAtFunc str_char_at_func = str.CharAtFunc();
19623 for (intptr_t i = 0; i < len; i++) {
19624 if (this_char_at_func(*this, i) !=
19625 str_char_at_func(str, begin_index + i)) {
19626 return false;
19627 }
19628 }
19629
19630 return true;
19631 }
19632
19633
19605 bool String::Equals(const char* cstr) const { 19634 bool String::Equals(const char* cstr) const {
19606 ASSERT(cstr != NULL); 19635 ASSERT(cstr != NULL);
19607 CodePointIterator it(*this); 19636 CodePointIterator it(*this);
19608 intptr_t len = strlen(cstr); 19637 intptr_t len = strlen(cstr);
19609 while (it.Next()) { 19638 while (it.Next()) {
19610 if (*cstr == '\0') { 19639 if (*cstr == '\0') {
19611 // Lengths don't match. 19640 // Lengths don't match.
19612 return false; 19641 return false;
19613 } 19642 }
19614 int32_t ch; 19643 int32_t ch;
(...skipping 3295 matching lines...) Expand 10 before | Expand all | Expand 10 after
22910 return tag_label.ToCString(); 22939 return tag_label.ToCString();
22911 } 22940 }
22912 22941
22913 22942
22914 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 22943 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
22915 Instance::PrintJSONImpl(stream, ref); 22944 Instance::PrintJSONImpl(stream, ref);
22916 } 22945 }
22917 22946
22918 22947
22919 } // namespace dart 22948 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698