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

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

Issue 1965823002: Initial isolate reload support (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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
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/parser.h" 5 #include "vm/parser.h"
6 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 4372 matching lines...) Expand 10 before | Expand all | Expand 10 after
4383 ReportError(", or } expected"); 4383 ReportError(", or } expected");
4384 } 4384 }
4385 } 4385 }
4386 ExpectToken(Token::kRBRACE); 4386 ExpectToken(Token::kRBRACE);
4387 4387
4388 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); 4388 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name));
4389 if (!obj.IsNull()) { 4389 if (!obj.IsNull()) {
4390 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); 4390 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString());
4391 } 4391 }
4392 Class& cls = Class::Handle(Z); 4392 Class& cls = Class::Handle(Z);
4393 cls = Class::New(*enum_name, script_, declaration_pos); 4393 cls = Class::New(library_, *enum_name, script_, declaration_pos);
4394 cls.set_library(library_);
4395 library_.AddClass(cls); 4394 library_.AddClass(cls);
4396 cls.set_is_synthesized_class(); 4395 cls.set_is_synthesized_class();
4397 cls.set_is_enum_class(); 4396 cls.set_is_enum_class();
4398 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { 4397 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) {
4399 library_.AddClassMetadata(cls, tl_owner, metadata_pos); 4398 library_.AddClassMetadata(cls, tl_owner, metadata_pos);
4400 } 4399 }
4401 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); 4400 cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
4402 pending_classes.Add(cls, Heap::kOld); 4401 pending_classes.Add(cls, Heap::kOld);
4403 } 4402 }
4404 4403
(...skipping 22 matching lines...) Expand all
4427 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); 4426 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
4428 } 4427 }
4429 Class& cls = Class::Handle(Z); 4428 Class& cls = Class::Handle(Z);
4430 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); 4429 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z);
4431 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); 4430 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name));
4432 if (obj.IsNull()) { 4431 if (obj.IsNull()) {
4433 if (is_patch) { 4432 if (is_patch) {
4434 ReportError(classname_pos, "missing class '%s' cannot be patched", 4433 ReportError(classname_pos, "missing class '%s' cannot be patched",
4435 class_name.ToCString()); 4434 class_name.ToCString());
4436 } 4435 }
4437 cls = Class::New(class_name, script_, declaration_pos); 4436 cls = Class::New(library_, class_name, script_, declaration_pos);
4438 library_.AddClass(cls); 4437 library_.AddClass(cls);
4439 } else { 4438 } else {
4440 if (!obj.IsClass()) { 4439 if (!obj.IsClass()) {
4441 ReportError(classname_pos, "'%s' is already defined", 4440 ReportError(classname_pos, "'%s' is already defined",
4442 class_name.ToCString()); 4441 class_name.ToCString());
4443 } 4442 }
4444 cls ^= obj.raw(); 4443 cls ^= obj.raw();
4445 if (is_patch) { 4444 if (is_patch) {
4446 // Preserve and reuse the original type parameters and bounds since the 4445 // Preserve and reuse the original type parameters and bounds since the
4447 // ones defined in the patch class will not be finalized. 4446 // ones defined in the patch class will not be finalized.
4448 orig_type_parameters = cls.type_parameters(); 4447 orig_type_parameters = cls.type_parameters();
4449 cls = Class::New(class_name, script_, declaration_pos); 4448 cls = Class::New(library_, class_name, script_, declaration_pos);
4450 cls.set_library(library_);
4451 } else { 4449 } else {
4452 // Not patching a class, but it has been found. This must be one of the 4450 // Not patching a class, but it has been found. This must be one of the
4453 // pre-registered classes from object.cc or a duplicate definition. 4451 // pre-registered classes from object.cc or a duplicate definition.
4454 if (!(cls.is_prefinalized() || 4452 if (!(cls.is_prefinalized() ||
4455 RawObject::IsImplicitFieldClassId(cls.id()))) { 4453 RawObject::IsImplicitFieldClassId(cls.id()))) {
4456 ReportError(classname_pos, "class '%s' is already defined", 4454 ReportError(classname_pos, "class '%s' is already defined",
4457 class_name.ToCString()); 4455 class_name.ToCString());
4458 } 4456 }
4459 // Pre-registered classes need their scripts connected at this time. 4457 // Pre-registered classes need their scripts connected at this time.
4460 cls.set_script(script_); 4458 cls.set_script(script_);
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
4910 if (FLAG_trace_parser) { 4908 if (FLAG_trace_parser) {
4911 OS::Print("toplevel parsing mixin application alias class '%s'\n", 4909 OS::Print("toplevel parsing mixin application alias class '%s'\n",
4912 class_name.ToCString()); 4910 class_name.ToCString());
4913 } 4911 }
4914 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); 4912 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name));
4915 if (!obj.IsNull()) { 4913 if (!obj.IsNull()) {
4916 ReportError(classname_pos, "'%s' is already defined", 4914 ReportError(classname_pos, "'%s' is already defined",
4917 class_name.ToCString()); 4915 class_name.ToCString());
4918 } 4916 }
4919 const Class& mixin_application = 4917 const Class& mixin_application =
4920 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); 4918 Class::Handle(Z, Class::New(library_, class_name,
4919 script_, classname_pos));
4921 mixin_application.set_is_mixin_app_alias(); 4920 mixin_application.set_is_mixin_app_alias();
4922 library_.AddClass(mixin_application); 4921 library_.AddClass(mixin_application);
4923 set_current_class(mixin_application); 4922 set_current_class(mixin_application);
4924 ParseTypeParameters(mixin_application); 4923 ParseTypeParameters(mixin_application);
4925 4924
4926 ExpectToken(Token::kASSIGN); 4925 ExpectToken(Token::kASSIGN);
4927 4926
4928 if (CurrentToken() == Token::kABSTRACT) { 4927 if (CurrentToken() == Token::kABSTRACT) {
4929 mixin_application.set_is_abstract(); 4928 mixin_application.set_is_abstract();
4930 ConsumeToken(); 4929 ConsumeToken();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
5038 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); 5037 Object::Handle(Z, library_.LookupLocalObject(*alias_name));
5039 if (!obj.IsNull()) { 5038 if (!obj.IsNull()) {
5040 ReportError(alias_name_pos, 5039 ReportError(alias_name_pos,
5041 "'%s' is already defined", alias_name->ToCString()); 5040 "'%s' is already defined", alias_name->ToCString());
5042 } 5041 }
5043 5042
5044 // Create the function type alias scope class. It will be linked to its 5043 // Create the function type alias scope class. It will be linked to its
5045 // signature function after it has been parsed. The type parameters, in order 5044 // signature function after it has been parsed. The type parameters, in order
5046 // to be properly finalized, need to be associated to this scope class as 5045 // to be properly finalized, need to be associated to this scope class as
5047 // they are parsed. 5046 // they are parsed.
5048 const Class& function_type_alias = Class::Handle(Z, 5047 const Class& function_type_alias =
5049 Class::New(*alias_name, script_, declaration_pos)); 5048 Class::Handle(Z, Class::New(
5049 library_, *alias_name, script_, declaration_pos));
5050 function_type_alias.set_is_synthesized_class(); 5050 function_type_alias.set_is_synthesized_class();
5051 function_type_alias.set_is_abstract(); 5051 function_type_alias.set_is_abstract();
5052 function_type_alias.set_is_prefinalized(); 5052 function_type_alias.set_is_prefinalized();
5053 library_.AddClass(function_type_alias); 5053 library_.AddClass(function_type_alias);
5054 set_current_class(function_type_alias); 5054 set_current_class(function_type_alias);
5055 // Parse the type parameters of the function type. 5055 // Parse the type parameters of the function type.
5056 ParseTypeParameters(function_type_alias); 5056 ParseTypeParameters(function_type_alias);
5057 // At this point, the type parameters have been parsed, so we can resolve the 5057 // At this point, the type parameters have been parsed, so we can resolve the
5058 // result type. 5058 // result type.
5059 if (!result_type.IsNull()) { 5059 if (!result_type.IsNull()) {
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after
6089 ObjectStore* object_store = I->object_store(); 6089 ObjectStore* object_store = I->object_store();
6090 const GrowableObjectArray& pending_classes = 6090 const GrowableObjectArray& pending_classes =
6091 GrowableObjectArray::Handle(Z, object_store->pending_classes()); 6091 GrowableObjectArray::Handle(Z, object_store->pending_classes());
6092 SetPosition(TokenPosition::kMinSource); 6092 SetPosition(TokenPosition::kMinSource);
6093 is_top_level_ = true; 6093 is_top_level_ = true;
6094 TopLevel top_level(Z); 6094 TopLevel top_level(Z);
6095 6095
6096 Object& tl_owner = Object::Handle(Z); 6096 Object& tl_owner = Object::Handle(Z);
6097 Class& toplevel_class = Class::Handle(Z, library_.toplevel_class()); 6097 Class& toplevel_class = Class::Handle(Z, library_.toplevel_class());
6098 if (toplevel_class.IsNull()) { 6098 if (toplevel_class.IsNull()) {
6099 toplevel_class = Class::New(Symbols::TopLevel(), script_, TokenPos()); 6099 toplevel_class =
6100 Class::New(library_, Symbols::TopLevel(), script_, TokenPos());
6100 toplevel_class.set_library(library_); 6101 toplevel_class.set_library(library_);
6101 library_.set_toplevel_class(toplevel_class); 6102 library_.set_toplevel_class(toplevel_class);
6102 tl_owner = toplevel_class.raw(); 6103 tl_owner = toplevel_class.raw();
6103 } else { 6104 } else {
6104 tl_owner = PatchClass::New(toplevel_class, script_); 6105 tl_owner = PatchClass::New(toplevel_class, script_);
6105 } 6106 }
6106 6107
6107 if (is_library_source() || is_patch_source()) { 6108 if (is_library_source() || is_patch_source()) {
6108 set_current_class(toplevel_class); 6109 set_current_class(toplevel_class);
6109 ParseLibraryDefinition(tl_owner); 6110 ParseLibraryDefinition(tl_owner);
(...skipping 5894 matching lines...) Expand 10 before | Expand all | Expand 10 after
12004 12005
12005 bool Parser::IsInstantiatorRequired() const { 12006 bool Parser::IsInstantiatorRequired() const {
12006 ASSERT(!current_function().IsNull()); 12007 ASSERT(!current_function().IsNull());
12007 if (current_function().is_static() && 12008 if (current_function().is_static() &&
12008 !current_function().IsInFactoryScope()) { 12009 !current_function().IsInFactoryScope()) {
12009 return false; 12010 return false;
12010 } 12011 }
12011 return current_class().IsGeneric(); 12012 return current_class().IsGeneric();
12012 } 12013 }
12013 12014
12014 // We cache computed compile-time constants in a map so we can look them
12015 // up when the same code gets compiled again. The map key is a pair
12016 // (script url, token position) which is encoded in an array with 2
12017 // elements:
12018 // - key[0] contains the canonicalized url of the script.
12019 // - key[1] contains the token position of the constant in the script.
12020 12015
12021 // ConstantPosKey allows us to look up a constant in the map without 12016 void Parser::InsertCachedConstantValue(const String& url,
12022 // allocating a key pair (array). 12017 TokenPosition token_pos,
12023 struct ConstantPosKey : ValueObject { 12018 const Instance& value) {
12024 ConstantPosKey(const String& url, TokenPosition pos) 12019 Isolate* isolate = Isolate::Current();
12025 : script_url(url), token_pos(pos) { } 12020 ConstantPosKey key(url, token_pos);
12026 const String& script_url; 12021 if (isolate->object_store()->compile_time_constants() == Array::null()) {
12027 TokenPosition token_pos; 12022 const intptr_t kInitialConstMapSize = 16;
12028 }; 12023 isolate->object_store()->set_compile_time_constants(
12029 12024 Array::Handle(HashTables::New<ConstantsMap>(kInitialConstMapSize,
12030 12025 Heap::kNew)));
12031 class ConstMapKeyEqualsTraits {
12032 public:
12033 static const char* Name() { return "ConstMapKeyEqualsTraits"; }
12034 static bool ReportStats() { return false; }
12035
12036 static bool IsMatch(const Object& a, const Object& b) {
12037 const Array& key1 = Array::Cast(a);
12038 const Array& key2 = Array::Cast(b);
12039 // Compare raw strings of script url symbol and raw smi of token positon.
12040 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1));
12041 } 12026 }
12042 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { 12027 ConstantsMap constants(isolate->object_store()->compile_time_constants());
12043 const Array& key2 = Array::Cast(b); 12028 constants.InsertNewOrGetValue(key, value);
12044 // Compare raw strings of script url symbol and token positon. 12029 isolate->object_store()->set_compile_time_constants(constants.Release());
12045 return (key1.script_url.raw() == key2.At(0)) 12030 }
12046 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1))));
12047 }
12048 static uword Hash(const Object& obj) {
12049 const Array& key = Array::Cast(obj);
12050 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0)));
12051 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1)));
12052 return HashValue(url_hash, pos);
12053 }
12054 static uword Hash(const ConstantPosKey& key) {
12055 return HashValue(String::HashRawSymbol(key.script_url.raw()),
12056 key.token_pos.value());
12057 }
12058 // Used by CacheConstantValue if a new constant is added to the map.
12059 static RawObject* NewKey(const ConstantPosKey& key) {
12060 const Array& key_obj = Array::Handle(Array::New(2));
12061 key_obj.SetAt(0, key.script_url);
12062 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value())));
12063 return key_obj.raw();;
12064 }
12065
12066 private:
12067 static uword HashValue(intptr_t url_hash, intptr_t pos) {
12068 return url_hash * pos % (Smi::kMaxValue - 13);
12069 }
12070 };
12071 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;
12072 12031
12073 12032
12074 void Parser::CacheConstantValue(TokenPosition token_pos, 12033 void Parser::CacheConstantValue(TokenPosition token_pos,
12075 const Instance& value) { 12034 const Instance& value) {
12076 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) { 12035 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) {
12077 // Don't cache constants in initializer expressions. They get 12036 // Don't cache constants in initializer expressions. They get
12078 // evaluated only once. 12037 // evaluated only once.
12079 return; 12038 return;
12080 } 12039 }
12081 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); 12040 const String& url = String::Handle(Z, script_.url());
12082 if (isolate()->object_store()->compile_time_constants() == Array::null()) { 12041 InsertCachedConstantValue(url, token_pos, value);
12083 const intptr_t kInitialConstMapSize = 16; 12042 if (FLAG_compiler_stats) {
12084 isolate()->object_store()->set_compile_time_constants( 12043 ConstantsMap constants(isolate()->object_store()->compile_time_constants());
12085 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, 12044 thread_->compiler_stats()->num_cached_consts = constants.NumOccupied();
12086 Heap::kNew))); 12045 constants.Release();
12087 } 12046 }
12088 ConstantsMap constants(isolate()->object_store()->compile_time_constants());
12089 constants.InsertNewOrGetValue(key, value);
12090 if (FLAG_compiler_stats) {
12091 thread_->compiler_stats()->num_cached_consts = constants.NumOccupied();
12092 }
12093 isolate()->object_store()->set_compile_time_constants(constants.Release());
12094 } 12047 }
12095 12048
12096 12049
12097 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { 12050 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) {
12098 if (isolate()->object_store()->compile_time_constants() == Array::null()) { 12051 if (isolate()->object_store()->compile_time_constants() == Array::null()) {
12099 return false; 12052 return false;
12100 } 12053 }
12101 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); 12054 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
12102 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); 12055 ConstantsMap constants(isolate()->object_store()->compile_time_constants());
12103 bool is_present = false; 12056 bool is_present = false;
(...skipping 2423 matching lines...) Expand 10 before | Expand all | Expand 10 after
14527 return Object::null(); 14480 return Object::null();
14528 } 14481 }
14529 14482
14530 14483
14531 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { 14484 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) {
14532 UNREACHABLE(); 14485 UNREACHABLE();
14533 return NULL; 14486 return NULL;
14534 } 14487 }
14535 14488
14536 14489
14490 void Parser::InsertCachedConstantValue(const String& url,
14491 TokenPosition token_pos,
14492 const Instance& value) {
14493 UNREACHABLE();
14494 }
14495
14496
14537 ArgumentListNode* Parser::BuildNoSuchMethodArguments( 14497 ArgumentListNode* Parser::BuildNoSuchMethodArguments(
14538 TokenPosition call_pos, 14498 TokenPosition call_pos,
14539 const String& function_name, 14499 const String& function_name,
14540 const ArgumentListNode& function_args, 14500 const ArgumentListNode& function_args,
14541 const LocalVariable* temp_for_last_arg, 14501 const LocalVariable* temp_for_last_arg,
14542 bool is_super_invocation) { 14502 bool is_super_invocation) {
14543 UNREACHABLE(); 14503 UNREACHABLE();
14544 return NULL; 14504 return NULL;
14545 } 14505 }
14546 14506
14547 } // namespace dart 14507 } // namespace dart
14548 14508
14549 #endif // DART_PRECOMPILED_RUNTIME 14509 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/parser.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698