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

Side by Side Diff: src/parsing/parser.cc

Issue 2198043002: Add a mode to completely deserialize scope chains (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 4 years, 4 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
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/test-parsing.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast.h" 10 #include "src/ast/ast.h"
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 } 850 }
851 if (info->ast_value_factory() == NULL) { 851 if (info->ast_value_factory() == NULL) {
852 // info takes ownership of AstValueFactory. 852 // info takes ownership of AstValueFactory.
853 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 853 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
854 info->set_ast_value_factory_owned(); 854 info->set_ast_value_factory_owned();
855 ast_value_factory_ = info->ast_value_factory(); 855 ast_value_factory_ = info->ast_value_factory();
856 ast_node_factory_.set_ast_value_factory(ast_value_factory_); 856 ast_node_factory_.set_ast_value_factory(ast_value_factory_);
857 } 857 }
858 } 858 }
859 859
860 void Parser::DeserializeScopeChain(
861 ParseInfo* info, Handle<Context> context,
862 Scope::DeserializationMode deserialization_mode) {
863 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
864 // context, which will have the "this" binding for script scopes.
865 Scope* scope = NewScriptScope();
866 info->set_script_scope(scope);
867 if (!context.is_null() && !context->IsNativeContext()) {
868 scope =
869 Scope::DeserializeScopeChain(info->isolate(), zone(), *context, scope,
870 ast_value_factory(), deserialization_mode);
871 if (info->context().is_null()) {
872 DCHECK(deserialization_mode ==
873 Scope::DeserializationMode::kDeserializeOffHeap);
874 } else {
875 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
876 // means the Parser cannot operate independent of the V8 heap. Tell the
877 // string table to internalize strings and values right after they're
878 // created. This kind of parsing can only be done in the main thread.
879 DCHECK(parsing_on_main_thread_);
880 ast_value_factory()->Internalize(info->isolate());
881 }
882 }
883 original_scope_ = scope;
884 }
860 885
861 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { 886 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
862 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 887 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
863 // see comment for HistogramTimerScope class. 888 // see comment for HistogramTimerScope class.
864 889
865 // It's OK to use the Isolate & counters here, since this function is only 890 // It's OK to use the Isolate & counters here, since this function is only
866 // called in the main thread. 891 // called in the main thread.
867 DCHECK(parsing_on_main_thread_); 892 DCHECK(parsing_on_main_thread_);
868 893
869 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); 894 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
870 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse); 895 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse);
871 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.Parse"); 896 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.Parse");
872 Handle<String> source(String::cast(info->script()->source())); 897 Handle<String> source(String::cast(info->script()->source()));
873 isolate->counters()->total_parse_size()->Increment(source->length()); 898 isolate->counters()->total_parse_size()->Increment(source->length());
874 base::ElapsedTimer timer; 899 base::ElapsedTimer timer;
875 if (FLAG_trace_parse) { 900 if (FLAG_trace_parse) {
876 timer.Start(); 901 timer.Start();
877 } 902 }
878 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 903 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
879 904
880 // Initialize parser state. 905 // Initialize parser state.
881 CompleteParserRecorder recorder; 906 CompleteParserRecorder recorder;
882 907
883 if (produce_cached_parse_data()) { 908 if (produce_cached_parse_data()) {
884 log_ = &recorder; 909 log_ = &recorder;
885 } else if (consume_cached_parse_data()) { 910 } else if (consume_cached_parse_data()) {
886 cached_parse_data_->Initialize(); 911 cached_parse_data_->Initialize();
887 } 912 }
888 913
914 DeserializeScopeChain(info, info->context(),
915 Scope::DeserializationMode::kKeepScopeInfo);
916
889 source = String::Flatten(source); 917 source = String::Flatten(source);
890 FunctionLiteral* result; 918 FunctionLiteral* result;
891 919
892 { 920 {
893 std::unique_ptr<Utf16CharacterStream> stream; 921 std::unique_ptr<Utf16CharacterStream> stream;
894 if (source->IsExternalTwoByteString()) { 922 if (source->IsExternalTwoByteString()) {
895 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( 923 stream.reset(new ExternalTwoByteStringUtf16CharacterStream(
896 Handle<ExternalTwoByteString>::cast(source), 0, source->length())); 924 Handle<ExternalTwoByteString>::cast(source), 0, source->length()));
897 } else if (source->IsExternalOneByteString()) { 925 } else if (source->IsExternalOneByteString()) {
898 stream.reset(new ExternalOneByteStringUtf16CharacterStream( 926 stream.reset(new ExternalOneByteStringUtf16CharacterStream(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 // background thread. We should not access anything Isolate / heap dependent 963 // background thread. We should not access anything Isolate / heap dependent
936 // via ParseInfo, and also not pass it forward. 964 // via ParseInfo, and also not pass it forward.
937 DCHECK_NULL(scope_state_); 965 DCHECK_NULL(scope_state_);
938 DCHECK_NULL(target_stack_); 966 DCHECK_NULL(target_stack_);
939 967
940 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; 968 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
941 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; 969 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
942 970
943 FunctionLiteral* result = NULL; 971 FunctionLiteral* result = NULL;
944 { 972 {
945 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native 973 Scope* scope = original_scope_;
946 // context, which will have the "this" binding for script scopes. 974 DCHECK(scope);
947 Scope* scope = NewScriptScope();
948 info->set_script_scope(scope);
949 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
950 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
951 *info->context(), scope,
952 ast_value_factory());
953 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
954 // means the Parser cannot operate independent of the V8 heap. Tell the
955 // string table to internalize strings and values right after they're
956 // created. This kind of parsing can only be done in the main thread.
957 DCHECK(parsing_on_main_thread_);
958 ast_value_factory()->Internalize(info->isolate());
959 }
960 original_scope_ = scope;
961 if (info->is_eval()) { 975 if (info->is_eval()) {
962 if (!scope->is_script_scope() || is_strict(info->language_mode())) { 976 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
963 parsing_mode = PARSE_EAGERLY; 977 parsing_mode = PARSE_EAGERLY;
964 } 978 }
965 scope = NewScopeWithParent(scope, EVAL_SCOPE); 979 scope = NewScopeWithParent(scope, EVAL_SCOPE);
966 } else if (info->is_module()) { 980 } else if (info->is_module()) {
967 scope = NewScopeWithParent(scope, MODULE_SCOPE); 981 scope = NewScopeWithParent(scope, MODULE_SCOPE);
968 } 982 }
969 983
970 scope->set_start_position(0); 984 scope->set_start_position(0);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); 1055 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy);
1042 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); 1056 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1043 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy"); 1057 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy");
1044 Handle<String> source(String::cast(info->script()->source())); 1058 Handle<String> source(String::cast(info->script()->source()));
1045 isolate->counters()->total_parse_size()->Increment(source->length()); 1059 isolate->counters()->total_parse_size()->Increment(source->length());
1046 base::ElapsedTimer timer; 1060 base::ElapsedTimer timer;
1047 if (FLAG_trace_parse) { 1061 if (FLAG_trace_parse) {
1048 timer.Start(); 1062 timer.Start();
1049 } 1063 }
1050 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 1064 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1065 DeserializeScopeChain(info, info->context(),
1066 Scope::DeserializationMode::kKeepScopeInfo);
1051 1067
1052 // Initialize parser state. 1068 // Initialize parser state.
1053 source = String::Flatten(source); 1069 source = String::Flatten(source);
1054 FunctionLiteral* result; 1070 FunctionLiteral* result;
1055 { 1071 {
1056 std::unique_ptr<Utf16CharacterStream> stream; 1072 std::unique_ptr<Utf16CharacterStream> stream;
1057 if (source->IsExternalTwoByteString()) { 1073 if (source->IsExternalTwoByteString()) {
1058 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( 1074 stream.reset(new ExternalTwoByteStringUtf16CharacterStream(
1059 Handle<ExternalTwoByteString>::cast(source), 1075 Handle<ExternalTwoByteString>::cast(source),
1060 shared_info->start_position(), shared_info->end_position())); 1076 shared_info->start_position(), shared_info->end_position()));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 const AstRawString* raw_name = ast_value_factory()->GetString(name); 1119 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1104 fni_->PushEnclosingName(raw_name); 1120 fni_->PushEnclosingName(raw_name);
1105 1121
1106 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1122 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1107 1123
1108 // Place holder for the result. 1124 // Place holder for the result.
1109 FunctionLiteral* result = nullptr; 1125 FunctionLiteral* result = nullptr;
1110 1126
1111 { 1127 {
1112 // Parse the function literal. 1128 // Parse the function literal.
1113 Scope* scope = NewScriptScope(); 1129 Scope* scope = original_scope_;
1114 info->set_script_scope(scope); 1130 DCHECK(scope);
1115 if (!info->context().is_null()) {
1116 // Ok to use Isolate here, since lazy function parsing is only done in the
1117 // main thread.
1118 DCHECK(parsing_on_main_thread_);
1119 scope = Scope::DeserializeScopeChain(isolate, zone(), *info->context(),
1120 scope, ast_value_factory());
1121 }
1122 original_scope_ = scope;
1123 FunctionState function_state(&function_state_, &scope_state_, scope, 1131 FunctionState function_state(&function_state_, &scope_state_, scope,
1124 shared_info->kind()); 1132 shared_info->kind());
1125 DCHECK(is_sloppy(scope->language_mode()) || 1133 DCHECK(is_sloppy(scope->language_mode()) ||
1126 is_strict(info->language_mode())); 1134 is_strict(info->language_mode()));
1127 DCHECK(info->language_mode() == shared_info->language_mode()); 1135 DCHECK(info->language_mode() == shared_info->language_mode());
1128 FunctionLiteral::FunctionType function_type = 1136 FunctionLiteral::FunctionType function_type =
1129 ComputeFunctionType(shared_info); 1137 ComputeFunctionType(shared_info);
1130 bool ok = true; 1138 bool ok = true;
1131 1139
1132 if (shared_info->is_arrow()) { 1140 if (shared_info->is_arrow()) {
(...skipping 4329 matching lines...) Expand 10 before | Expand all | Expand 10 after
5462 stream_ptr = info->character_stream(); 5470 stream_ptr = info->character_stream();
5463 } else { 5471 } else {
5464 DCHECK(info->character_stream() == nullptr); 5472 DCHECK(info->character_stream() == nullptr);
5465 stream.reset(new ExternalStreamingStream(info->source_stream(), 5473 stream.reset(new ExternalStreamingStream(info->source_stream(),
5466 info->source_stream_encoding())); 5474 info->source_stream_encoding()));
5467 stream_ptr = stream.get(); 5475 stream_ptr = stream.get();
5468 } 5476 }
5469 scanner_.Initialize(stream_ptr); 5477 scanner_.Initialize(stream_ptr);
5470 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); 5478 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5471 5479
5480 DCHECK(original_scope_);
5481
5472 // When streaming, we don't know the length of the source until we have parsed 5482 // When streaming, we don't know the length of the source until we have parsed
5473 // it. The raw data can be UTF-8, so we wouldn't know the source length until 5483 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5474 // we have decoded it anyway even if we knew the raw data length (which we 5484 // we have decoded it anyway even if we knew the raw data length (which we
5475 // don't). We work around this by storing all the scopes which need their end 5485 // don't). We work around this by storing all the scopes which need their end
5476 // position set at the end of the script (the top scope and possible eval 5486 // position set at the end of the script (the top scope and possible eval
5477 // scopes) and set their end position after we know the script length. 5487 // scopes) and set their end position after we know the script length.
5478 result = DoParseProgram(info); 5488 result = DoParseProgram(info);
5479 5489
5480 info->set_literal(result); 5490 info->set_literal(result);
5481 5491
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after
7087 node->Print(Isolate::Current()); 7097 node->Print(Isolate::Current());
7088 } 7098 }
7089 #endif // DEBUG 7099 #endif // DEBUG
7090 7100
7091 #undef CHECK_OK 7101 #undef CHECK_OK
7092 #undef CHECK_OK_VOID 7102 #undef CHECK_OK_VOID
7093 #undef CHECK_FAILED 7103 #undef CHECK_FAILED
7094 7104
7095 } // namespace internal 7105 } // namespace internal
7096 } // namespace v8 7106 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698