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

Side by Side Diff: vm/object.cc

Issue 11969029: Allow externalization of canonical strings also. Only restrict canonical strings (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 7 years, 11 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
« no previous file with comments | « vm/object.h ('k') | vm/object_test.cc » ('j') | 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/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 if (name.CharAt(j) != accessor_name.CharAt(i)) { 2258 if (name.CharAt(j) != accessor_name.CharAt(i)) {
2259 return false; 2259 return false;
2260 } 2260 }
2261 } 2261 }
2262 return true; 2262 return true;
2263 } 2263 }
2264 2264
2265 2265
2266 RawFunction* Class::LookupFunction(const String& name) const { 2266 RawFunction* Class::LookupFunction(const String& name) const {
2267 Isolate* isolate = Isolate::Current(); 2267 Isolate* isolate = Isolate::Current();
2268 ASSERT(name.IsOneByteString());
2269 Array& funcs = Array::Handle(isolate, functions()); 2268 Array& funcs = Array::Handle(isolate, functions());
2270 if (funcs.IsNull()) { 2269 if (funcs.IsNull()) {
2271 // This can occur, e.g., for Null classes. 2270 // This can occur, e.g., for Null classes.
2272 return Function::null(); 2271 return Function::null();
2273 } 2272 }
2274 Function& function = Function::Handle(isolate, Function::null()); 2273 Function& function = Function::Handle(isolate, Function::null());
2275 if (name.IsSymbol()) { 2274 if (name.IsSymbol()) {
2276 // Quick Symbol compare. 2275 // Quick Symbol compare.
2277 intptr_t len = funcs.Length(); 2276 intptr_t len = funcs.Length();
2278 for (intptr_t i = 0; i < len; i++) { 2277 for (intptr_t i = 0; i < len; i++) {
(...skipping 13 matching lines...) Expand all
2292 } 2291 }
2293 } 2292 }
2294 } 2293 }
2295 // No function found. 2294 // No function found.
2296 return Function::null(); 2295 return Function::null();
2297 } 2296 }
2298 2297
2299 2298
2300 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const { 2299 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const {
2301 Isolate* isolate = Isolate::Current(); 2300 Isolate* isolate = Isolate::Current();
2302 ASSERT(name.IsOneByteString());
2303 Array& funcs = Array::Handle(isolate, functions()); 2301 Array& funcs = Array::Handle(isolate, functions());
2304 if (funcs.IsNull()) { 2302 if (funcs.IsNull()) {
2305 // This can occur, e.g., for Null classes. 2303 // This can occur, e.g., for Null classes.
2306 return Function::null(); 2304 return Function::null();
2307 } 2305 }
2308 Function& function = Function::Handle(isolate, Function::null()); 2306 Function& function = Function::Handle(isolate, Function::null());
2309 String& function_name = String::Handle(isolate, String::null()); 2307 String& function_name = String::Handle(isolate, String::null());
2310 intptr_t len = funcs.Length(); 2308 intptr_t len = funcs.Length();
2311 for (intptr_t i = 0; i < len; i++) { 2309 for (intptr_t i = 0; i < len; i++) {
2312 function ^= funcs.At(i); 2310 function ^= funcs.At(i);
2313 function_name ^= function.name(); 2311 function_name ^= function.name();
2314 if (OneByteString::EqualsIgnoringPrivateKey(function_name, name)) { 2312 if (String::EqualsIgnoringPrivateKey(function_name, name)) {
2315 return function.raw(); 2313 return function.raw();
2316 } 2314 }
2317 } 2315 }
2318 // No function found. 2316 // No function found.
2319 return Function::null(); 2317 return Function::null();
2320 } 2318 }
2321 2319
2322 2320
2323 RawFunction* Class::LookupGetterFunction(const String& name) const { 2321 RawFunction* Class::LookupGetterFunction(const String& name) const {
2324 return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name); 2322 return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name);
2325 } 2323 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2398 } 2396 }
2399 return field.raw(); 2397 return field.raw();
2400 } 2398 }
2401 // No field found. 2399 // No field found.
2402 return Field::null(); 2400 return Field::null();
2403 } 2401 }
2404 2402
2405 2403
2406 RawField* Class::LookupField(const String& name) const { 2404 RawField* Class::LookupField(const String& name) const {
2407 Isolate* isolate = Isolate::Current(); 2405 Isolate* isolate = Isolate::Current();
2408 ASSERT(name.IsOneByteString());
2409 const Array& flds = Array::Handle(isolate, fields()); 2406 const Array& flds = Array::Handle(isolate, fields());
2410 Field& field = Field::Handle(isolate, Field::null()); 2407 Field& field = Field::Handle(isolate, Field::null());
2411 String& field_name = String::Handle(isolate, String::null()); 2408 String& field_name = String::Handle(isolate, String::null());
2412 intptr_t len = flds.Length(); 2409 intptr_t len = flds.Length();
2413 for (intptr_t i = 0; i < len; i++) { 2410 for (intptr_t i = 0; i < len; i++) {
2414 field ^= flds.At(i); 2411 field ^= flds.At(i);
2415 field_name ^= field.name(); 2412 field_name ^= field.name();
2416 if (OneByteString::EqualsIgnoringPrivateKey(field_name, name)) { 2413 if (String::EqualsIgnoringPrivateKey(field_name, name)) {
2417 return field.raw(); 2414 return field.raw();
2418 } 2415 }
2419 } 2416 }
2420 // No field found. 2417 // No field found.
2421 return Field::null(); 2418 return Field::null();
2422 } 2419 }
2423 2420
2424 2421
2425 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const { 2422 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const {
2426 Isolate* isolate = Isolate::Current(); 2423 Isolate* isolate = Isolate::Current();
2427 const Library& lib = Library::Handle(isolate, library()); 2424 const Library& lib = Library::Handle(isolate, library());
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
3960 3957
3961 3958
3962 RawFunction* Function::New(const String& name, 3959 RawFunction* Function::New(const String& name,
3963 RawFunction::Kind kind, 3960 RawFunction::Kind kind,
3964 bool is_static, 3961 bool is_static,
3965 bool is_const, 3962 bool is_const,
3966 bool is_abstract, 3963 bool is_abstract,
3967 bool is_external, 3964 bool is_external,
3968 const Object& owner, 3965 const Object& owner,
3969 intptr_t token_pos) { 3966 intptr_t token_pos) {
3970 ASSERT(name.IsOneByteString());
3971 ASSERT(!owner.IsNull()); 3967 ASSERT(!owner.IsNull());
3972 const Function& result = Function::Handle(Function::New()); 3968 const Function& result = Function::Handle(Function::New());
3973 result.set_parameter_types(Object::empty_array()); 3969 result.set_parameter_types(Object::empty_array());
3974 result.set_parameter_names(Object::empty_array()); 3970 result.set_parameter_names(Object::empty_array());
3975 result.set_name(name); 3971 result.set_name(name);
3976 result.set_kind(kind); 3972 result.set_kind(kind);
3977 result.set_is_static(is_static); 3973 result.set_is_static(is_static);
3978 result.set_is_const(is_const); 3974 result.set_is_const(is_const);
3979 result.set_is_abstract(is_abstract); 3975 result.set_is_abstract(is_abstract);
3980 result.set_is_external(is_external); 3976 result.set_is_external(is_external);
(...skipping 15 matching lines...) Expand all
3996 const ClosureData& data = ClosureData::Handle(ClosureData::New()); 3992 const ClosureData& data = ClosureData::Handle(ClosureData::New());
3997 result.set_data(data); 3993 result.set_data(data);
3998 } 3994 }
3999 return result.raw(); 3995 return result.raw();
4000 } 3996 }
4001 3997
4002 3998
4003 RawFunction* Function::NewClosureFunction(const String& name, 3999 RawFunction* Function::NewClosureFunction(const String& name,
4004 const Function& parent, 4000 const Function& parent,
4005 intptr_t token_pos) { 4001 intptr_t token_pos) {
4006 ASSERT(name.IsOneByteString());
4007 ASSERT(!parent.IsNull()); 4002 ASSERT(!parent.IsNull());
4008 // Use the owner defining the parent function and not the class containing it. 4003 // Use the owner defining the parent function and not the class containing it.
4009 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); 4004 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
4010 ASSERT(!parent_owner.IsNull()); 4005 ASSERT(!parent_owner.IsNull());
4011 const Function& result = Function::Handle( 4006 const Function& result = Function::Handle(
4012 Function::New(name, 4007 Function::New(name,
4013 RawFunction::kClosureFunction, 4008 RawFunction::kClosureFunction,
4014 /* is_static = */ parent.is_static(), 4009 /* is_static = */ parent.is_static(),
4015 /* is_const = */ false, 4010 /* is_const = */ false,
4016 /* is_abstract = */ false, 4011 /* is_abstract = */ false,
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
4519 return reinterpret_cast<RawField*>(raw); 4514 return reinterpret_cast<RawField*>(raw);
4520 } 4515 }
4521 4516
4522 4517
4523 RawField* Field::New(const String& name, 4518 RawField* Field::New(const String& name,
4524 bool is_static, 4519 bool is_static,
4525 bool is_final, 4520 bool is_final,
4526 bool is_const, 4521 bool is_const,
4527 const Class& owner, 4522 const Class& owner,
4528 intptr_t token_pos) { 4523 intptr_t token_pos) {
4529 ASSERT(name.IsOneByteString());
4530 ASSERT(!owner.IsNull()); 4524 ASSERT(!owner.IsNull());
4531 const Field& result = Field::Handle(Field::New()); 4525 const Field& result = Field::Handle(Field::New());
4532 result.set_name(name); 4526 result.set_name(name);
4533 result.set_is_static(is_static); 4527 result.set_is_static(is_static);
4534 if (is_static) { 4528 if (is_static) {
4535 result.set_value(Instance::Handle()); 4529 result.set_value(Instance::Handle());
4536 } else { 4530 } else {
4537 result.SetOffset(0); 4531 result.SetOffset(0);
4538 } 4532 }
4539 result.set_is_final(is_final); 4533 result.set_is_final(is_final);
(...skipping 6313 matching lines...) Expand 10 before | Expand all | Expand 10 after
10853 Dart_PeerFinalizer cback) const { 10847 Dart_PeerFinalizer cback) const {
10854 NoGCScope no_gc; 10848 NoGCScope no_gc;
10855 ASSERT(array != NULL); 10849 ASSERT(array != NULL);
10856 intptr_t str_length = this->Length(); 10850 intptr_t str_length = this->Length();
10857 ASSERT(length >= (str_length * this->CharSize())); 10851 ASSERT(length >= (str_length * this->CharSize()));
10858 intptr_t class_id = raw()->GetClassId(); 10852 intptr_t class_id = raw()->GetClassId();
10859 intptr_t used_size = 0; 10853 intptr_t used_size = 0;
10860 intptr_t original_size = 0; 10854 intptr_t original_size = 0;
10861 uword tags = raw_ptr()->tags_; 10855 uword tags = raw_ptr()->tags_;
10862 10856
10863 ASSERT(!IsCanonical()); 10857 ASSERT(!InVMHeap());
10864 if (class_id == kOneByteStringCid) { 10858 if (class_id == kOneByteStringCid) {
10865 used_size = ExternalOneByteString::InstanceSize(); 10859 used_size = ExternalOneByteString::InstanceSize();
10866 original_size = OneByteString::InstanceSize(str_length); 10860 original_size = OneByteString::InstanceSize(str_length);
10867 ASSERT(original_size >= used_size); 10861 ASSERT(original_size >= used_size);
10868 10862
10869 // Copy the data into the external array. 10863 // Copy the data into the external array.
10870 if (str_length > 0) { 10864 if (str_length > 0) {
10871 memmove(array, OneByteString::CharAddr(*this, 0), str_length); 10865 memmove(array, OneByteString::CharAddr(*this, 0), str_length);
10872 } 10866 }
10873 10867
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
10950 return Transform(CaseMapping::ToUpper, str, space); 10944 return Transform(CaseMapping::ToUpper, str, space);
10951 } 10945 }
10952 10946
10953 10947
10954 RawString* String::ToLowerCase(const String& str, Heap::Space space) { 10948 RawString* String::ToLowerCase(const String& str, Heap::Space space) {
10955 // TODO(cshapiro): create a fast-path for OneByteString instances. 10949 // TODO(cshapiro): create a fast-path for OneByteString instances.
10956 return Transform(CaseMapping::ToLower, str, space); 10950 return Transform(CaseMapping::ToLower, str, space);
10957 } 10951 }
10958 10952
10959 10953
10954 // Check to see if 'str1' matches 'str2' as is or
10955 // once the private key separator is stripped from str2.
10956 //
10957 // Things are made more complicated by the fact that constructors are
10958 // added *after* the private suffix, so "foo@123.named" should match
10959 // "foo.named".
10960 //
10961 // Also, the private suffix can occur more than once in the name, as in:
10962 //
10963 // _ReceivePortImpl@6be832b._internal@6be832b
10964 //
10965 template<typename T1, typename T2>
10966 static bool EqualsIgnoringPrivateKey(const String& str1,
10967 const String& str2) {
10968 intptr_t len = str1.Length();
10969 intptr_t str2_len = str2.Length();
10970 if (len == str2_len) {
10971 for (intptr_t i = 0; i < len; i++) {
10972 if (T1::CharAt(str1, i) != T2::CharAt(str2, i)) {
10973 return false;
10974 }
10975 }
10976 return true;
10977 }
10978 if (len < str2_len) {
10979 return false; // No way they can match.
10980 }
10981 intptr_t pos = 0;
10982 intptr_t str2_pos = 0;
10983 while (pos < len) {
10984 int32_t ch = T1::CharAt(str1, pos);
10985 pos++;
10986
10987 if (ch == Scanner::kPrivateKeySeparator) {
10988 // Consume a private key separator.
10989 while ((pos < len) && (T1::CharAt(str1, pos) != '.')) {
10990 pos++;
10991 }
10992 // Resume matching characters.
10993 continue;
10994 }
10995 if ((str2_pos == str2_len) || (ch != T2::CharAt(str2, str2_pos))) {
10996 return false;
10997 }
10998 str2_pos++;
10999 }
11000
11001 // We have reached the end of mangled_name string.
11002 ASSERT(pos == len);
11003 return (str2_pos == str2_len);
11004 }
11005
11006
11007 #define EQUALS_IGNORING_PRIVATE_KEY(class_id, type, str1, str2) \
11008 switch (class_id) { \
11009 case kOneByteStringCid : \
11010 return dart::EqualsIgnoringPrivateKey<type, OneByteString>(str1, str2); \
11011 case kTwoByteStringCid : \
11012 return dart::EqualsIgnoringPrivateKey<type, TwoByteString>(str1, str2); \
11013 case kExternalOneByteStringCid : \
11014 return dart::EqualsIgnoringPrivateKey<type, ExternalOneByteString>(str1, \
11015 str2);\
11016 case kExternalTwoByteStringCid : \
11017 return dart::EqualsIgnoringPrivateKey<type, ExternalTwoByteString>(str1, \
11018 str2);\
11019 } \
11020 UNREACHABLE(); \
11021
11022
11023 bool String::EqualsIgnoringPrivateKey(const String& str1,
11024 const String& str2) {
11025 if (str1.raw() == str2.raw()) {
11026 return true; // Both handles point to the same raw instance.
11027 }
11028 NoGCScope no_gc;
11029 intptr_t str1_class_id = str1.raw()->GetClassId();
11030 intptr_t str2_class_id = str2.raw()->GetClassId();
11031 switch (str1_class_id) {
11032 case kOneByteStringCid :
11033 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2);
11034 break;
11035 case kTwoByteStringCid :
11036 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, TwoByteString, str1, str2);
11037 break;
11038 case kExternalOneByteStringCid :
11039 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id,
11040 ExternalOneByteString, str1, str2);
11041 break;
11042 case kExternalTwoByteStringCid :
11043 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id,
11044 ExternalTwoByteString, str1, str2);
11045 break;
11046 }
11047 UNREACHABLE();
11048 return false;
11049 }
11050
11051
10960 bool String::CodePointIterator::Next() { 11052 bool String::CodePointIterator::Next() {
10961 ASSERT(index_ >= -1); 11053 ASSERT(index_ >= -1);
10962 intptr_t length = Utf16::Length(ch_); 11054 intptr_t length = Utf16::Length(ch_);
10963 if (index_ < (end_ - length)) { 11055 if (index_ < (end_ - length)) {
10964 index_ += length; 11056 index_ += length;
10965 ch_ = str_.CharAt(index_); 11057 ch_ = str_.CharAt(index_);
10966 if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) { 11058 if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) {
10967 int32_t ch2 = str_.CharAt(index_ + 1); 11059 int32_t ch2 = str_.CharAt(index_ + 1);
10968 if (Utf16::IsTrailSurrogate(ch2)) { 11060 if (Utf16::IsTrailSurrogate(ch2)) {
10969 ch_ = Utf16::Decode(ch_, ch2); 11061 ch_ = Utf16::Decode(ch_, ch2);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
11003 *(CharAddr(dststr, index)) = *CharAddr(str, i); 11095 *(CharAddr(dststr, index)) = *CharAddr(str, i);
11004 index += 1; 11096 index += 1;
11005 } 11097 }
11006 } 11098 }
11007 return OneByteString::raw(dststr); 11099 return OneByteString::raw(dststr);
11008 } 11100 }
11009 return OneByteString::null(); 11101 return OneByteString::null();
11010 } 11102 }
11011 11103
11012 11104
11013 // Check to see if 'str1' matches 'str2' as is or
11014 // once the private key separator is stripped from str2.
11015 //
11016 // Things are made more complicated by the fact that constructors are
11017 // added *after* the private suffix, so "foo@123.named" should match
11018 // "foo.named".
11019 //
11020 // Also, the private suffix can occur more than once in the name, as in:
11021 //
11022 // _ReceivePortImpl@6be832b._internal@6be832b
11023 //
11024 bool OneByteString::EqualsIgnoringPrivateKey(const String& str1,
11025 const String& str2) {
11026 ASSERT(str2.IsOneByteString());
11027 if (str1.raw() == str2.raw()) {
11028 return true; // Both handles point to the same raw instance.
11029 }
11030 NoGCScope no_gc;
11031 intptr_t len = str1.Length();
11032 intptr_t str2_len = str2.Length();
11033 if (len == str2_len) {
11034 for (intptr_t i = 0; i < len; i++) {
11035 if (*CharAddr(str1, i) != *CharAddr(str2, i)) {
11036 return false;
11037 }
11038 }
11039 return true;
11040 }
11041 if (len < str2_len) {
11042 return false; // No way they can match.
11043 }
11044 intptr_t pos = 0;
11045 intptr_t str2_pos = 0;
11046 while (pos < len) {
11047 int32_t ch = *CharAddr(str1, pos);
11048 pos++;
11049
11050 if (ch == Scanner::kPrivateKeySeparator) {
11051 // Consume a private key separator.
11052 while ((pos < len) && (*CharAddr(str1, pos) != '.')) {
11053 pos++;
11054 }
11055 // Resume matching characters.
11056 continue;
11057 }
11058 if ((str2_pos == str2_len) || (ch != *CharAddr(str2, str2_pos))) {
11059 return false;
11060 }
11061 str2_pos++;
11062 }
11063
11064 // We have reached the end of mangled_name string.
11065 ASSERT(pos == len);
11066 return (str2_pos == str2_len);
11067 }
11068
11069
11070 RawOneByteString* OneByteString::New(intptr_t len, 11105 RawOneByteString* OneByteString::New(intptr_t len,
11071 Heap::Space space) { 11106 Heap::Space space) {
11072 ASSERT(Isolate::Current() == Dart::vm_isolate() || 11107 ASSERT(Isolate::Current() == Dart::vm_isolate() ||
11073 Isolate::Current()->object_store()->one_byte_string_class() != 11108 Isolate::Current()->object_store()->one_byte_string_class() !=
11074 Class::null()); 11109 Class::null());
11075 if (len < 0 || len > kMaxElements) { 11110 if (len < 0 || len > kMaxElements) {
11076 // This should be caught before we reach here. 11111 // This should be caught before we reach here.
11077 FATAL1("Fatal error in OneByteString::New: invalid len %"Pd"\n", len); 11112 FATAL1("Fatal error in OneByteString::New: invalid len %"Pd"\n", len);
11078 } 11113 }
11079 String& result = String::Handle(); 11114 String& result = String::Handle();
(...skipping 1515 matching lines...) Expand 10 before | Expand all | Expand 10 after
12595 } 12630 }
12596 return result.raw(); 12631 return result.raw();
12597 } 12632 }
12598 12633
12599 12634
12600 const char* WeakProperty::ToCString() const { 12635 const char* WeakProperty::ToCString() const {
12601 return "_WeakProperty"; 12636 return "_WeakProperty";
12602 } 12637 }
12603 12638
12604 } // namespace dart 12639 } // namespace dart
OLDNEW
« no previous file with comments | « vm/object.h ('k') | vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698