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

Side by Side Diff: src/compiler.cc

Issue 1258503003: Debugger: correctly recompile toplevel eval functions for debugging. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add comment Created 5 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/compiler.h ('k') | src/debug.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/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/ast-numbering.h" 9 #include "src/ast-numbering.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 : CompilationInfo(parse_info, nullptr, BASE, parse_info->isolate(), 105 : CompilationInfo(parse_info, nullptr, BASE, parse_info->isolate(),
106 parse_info->zone()) { 106 parse_info->zone()) {
107 // Compiling for the snapshot typically results in different code than 107 // Compiling for the snapshot typically results in different code than
108 // compiling later on. This means that code recompiled with deoptimization 108 // compiling later on. This means that code recompiled with deoptimization
109 // support won't be "equivalent" (as defined by SharedFunctionInfo:: 109 // support won't be "equivalent" (as defined by SharedFunctionInfo::
110 // EnableDeoptimizationSupport), so it will replace the old code and all 110 // EnableDeoptimizationSupport), so it will replace the old code and all
111 // its type feedback. To avoid this, always compile functions in the snapshot 111 // its type feedback. To avoid this, always compile functions in the snapshot
112 // with deoptimization support. 112 // with deoptimization support.
113 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); 113 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
114 114
115 if (isolate_->debug()->is_active()) MarkAsDebug();
116 if (FLAG_context_specialization) MarkAsContextSpecializing(); 115 if (FLAG_context_specialization) MarkAsContextSpecializing();
117 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); 116 if (FLAG_turbo_inlining) MarkAsInliningEnabled();
118 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); 117 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled();
119 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); 118 if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
120 if (FLAG_turbo_types) MarkAsTypingEnabled(); 119 if (FLAG_turbo_types) MarkAsTypingEnabled();
121 120
122 if (has_shared_info()) { 121 if (has_shared_info()) {
123 if (shared_info()->is_compiled()) { 122 if (shared_info()->is_compiled()) {
124 // We should initialize the CompilationInfo feedback vector from the 123 // We should initialize the CompilationInfo feedback vector from the
125 // passed in shared info, rather than creating a new one. 124 // passed in shared info, rather than creating a new one.
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 shared->set_scope_info(*target_scope_info); 958 shared->set_scope_info(*target_scope_info);
960 } 959 }
961 960
962 // The existing unoptimized code was replaced with the new one. 961 // The existing unoptimized code was replaced with the new one.
963 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); 962 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
964 } 963 }
965 return true; 964 return true;
966 } 965 }
967 966
968 967
969 MaybeHandle<Code> CompileForDebugging(CompilationInfo* info) { 968 bool CompileEvalForDebugging(Handle<JSFunction> function,
970 info->MarkAsDebug(); 969 Handle<SharedFunctionInfo> shared) {
971 VMState<COMPILER> state(info->isolate()); 970 Handle<Script> script(Script::cast(shared->script()));
972 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(info); 971 Handle<Context> context(function->context());
973 Handle<Code> new_code; 972
974 if (!maybe_new_code.ToHandle(&new_code)) { 973 Zone zone;
975 info->isolate()->clear_pending_exception(); 974 ParseInfo parse_info(&zone, script);
975 CompilationInfo info(&parse_info);
976 Isolate* isolate = info.isolate();
977
978 parse_info.set_eval();
979 parse_info.set_context(context);
980 if (context->IsNativeContext()) parse_info.set_global();
981 parse_info.set_toplevel();
982 parse_info.set_allow_lazy_parsing(false);
983 parse_info.set_language_mode(shared->language_mode());
984 parse_info.set_parse_restriction(NO_PARSE_RESTRICTION);
985 info.MarkAsDebug();
986
987 VMState<COMPILER> state(info.isolate());
988
989 if (!Parser::ParseStatic(&parse_info)) {
990 isolate->clear_pending_exception();
991 return false;
976 } 992 }
977 return maybe_new_code; 993
994 FunctionLiteral* lit = info.function();
995 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
996
997 if (!CompileUnoptimizedCode(&info)) {
998 isolate->clear_pending_exception();
999 return false;
1000 }
1001 shared->ReplaceCode(*info.code());
1002 return true;
978 } 1003 }
979 1004
980 1005
981 MaybeHandle<Code> Compiler::GetDebugCode(Handle<JSFunction> function) { 1006 bool CompileForDebugging(CompilationInfo* info) {
982 CompilationInfoWithZone info(function); 1007 info->MarkAsDebug();
983 VMState<COMPILER> state(info.isolate()); 1008 if (GetUnoptimizedCodeCommon(info).is_null()) {
984 return CompileForDebugging(&info); 1009 info->isolate()->clear_pending_exception();
1010 return false;
1011 }
1012 return true;
985 } 1013 }
986 1014
987 1015
988 MaybeHandle<Code> Compiler::GetDebugCode(Handle<SharedFunctionInfo> shared) { 1016 bool Compiler::CompileDebugCode(Handle<JSFunction> function) {
1017 Handle<SharedFunctionInfo> shared(function->shared());
1018 if (shared->is_toplevel() && shared->script()->IsScript() &&
1019 Script::cast(shared->script())->compilation_type() ==
1020 Script::COMPILATION_TYPE_EVAL) {
1021 return CompileEvalForDebugging(function, shared);
1022 } else {
1023 CompilationInfoWithZone info(function);
1024 return CompileForDebugging(&info);
1025 }
1026 }
1027
1028
1029 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) {
989 DCHECK(shared->allows_lazy_compilation_without_context()); 1030 DCHECK(shared->allows_lazy_compilation_without_context());
990 Zone zone; 1031 Zone zone;
991 ParseInfo parse_info(&zone, shared); 1032 ParseInfo parse_info(&zone, shared);
992 CompilationInfo info(&parse_info); 1033 CompilationInfo info(&parse_info);
993 return CompileForDebugging(&info); 1034 return CompileForDebugging(&info);
994 } 1035 }
995 1036
996 1037
997 void Compiler::CompileForLiveEdit(Handle<Script> script) { 1038 void Compiler::CompileForLiveEdit(Handle<Script> script) {
998 // TODO(635): support extensions. 1039 // TODO(635): support extensions.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 // the instances of the function. 1154 // the instances of the function.
1114 SetExpectedNofPropertiesFromEstimate(result, 1155 SetExpectedNofPropertiesFromEstimate(result,
1115 lit->expected_property_count()); 1156 lit->expected_property_count());
1116 1157
1117 if (!script.is_null()) 1158 if (!script.is_null())
1118 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); 1159 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
1119 1160
1120 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); 1161 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
1121 } 1162 }
1122 1163
1123 isolate->debug()->OnAfterCompile(script);
1124
1125 return result; 1164 return result;
1126 } 1165 }
1127 1166
1128 1167
1129 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( 1168 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
1130 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 1169 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
1131 Handle<Context> context, LanguageMode language_mode, 1170 Handle<Context> context, LanguageMode language_mode,
1132 ParseRestriction restriction, int line_offset, int column_offset, 1171 ParseRestriction restriction, int line_offset, int column_offset,
1133 Handle<Object> script_name, ScriptOriginOptions options) { 1172 Handle<Object> script_name, ScriptOriginOptions options) {
1134 Isolate* isolate = source->GetIsolate(); 1173 Isolate* isolate = source->GetIsolate();
1135 int source_length = source->length(); 1174 int source_length = source->length();
1136 isolate->counters()->total_eval_size()->Increment(source_length); 1175 isolate->counters()->total_eval_size()->Increment(source_length);
1137 isolate->counters()->total_compile_size()->Increment(source_length); 1176 isolate->counters()->total_compile_size()->Increment(source_length);
1138 1177
1139 CompilationCache* compilation_cache = isolate->compilation_cache(); 1178 CompilationCache* compilation_cache = isolate->compilation_cache();
1140 MaybeHandle<SharedFunctionInfo> maybe_shared_info = 1179 MaybeHandle<SharedFunctionInfo> maybe_shared_info =
1141 compilation_cache->LookupEval(source, outer_info, context, language_mode, 1180 compilation_cache->LookupEval(source, outer_info, context, language_mode,
1142 line_offset); 1181 line_offset);
1143 Handle<SharedFunctionInfo> shared_info; 1182 Handle<SharedFunctionInfo> shared_info;
1144 1183
1184 Handle<Script> script;
1145 if (!maybe_shared_info.ToHandle(&shared_info)) { 1185 if (!maybe_shared_info.ToHandle(&shared_info)) {
1146 Handle<Script> script = isolate->factory()->NewScript(source); 1186 script = isolate->factory()->NewScript(source);
1147 if (!script_name.is_null()) { 1187 if (!script_name.is_null()) {
1148 script->set_name(*script_name); 1188 script->set_name(*script_name);
1149 script->set_line_offset(Smi::FromInt(line_offset)); 1189 script->set_line_offset(Smi::FromInt(line_offset));
1150 script->set_column_offset(Smi::FromInt(column_offset)); 1190 script->set_column_offset(Smi::FromInt(column_offset));
1151 } 1191 }
1152 script->set_origin_options(options); 1192 script->set_origin_options(options);
1153 Zone zone; 1193 Zone zone;
1154 ParseInfo parse_info(&zone, script); 1194 ParseInfo parse_info(&zone, script);
1155 CompilationInfo info(&parse_info); 1195 CompilationInfo info(&parse_info);
1156 parse_info.set_eval(); 1196 parse_info.set_eval();
1157 if (context->IsNativeContext()) parse_info.set_global(); 1197 if (context->IsNativeContext()) parse_info.set_global();
1158 parse_info.set_language_mode(language_mode); 1198 parse_info.set_language_mode(language_mode);
1159 parse_info.set_parse_restriction(restriction); 1199 parse_info.set_parse_restriction(restriction);
1160 parse_info.set_context(context); 1200 parse_info.set_context(context);
1161 1201
1162 // If we eval from debug code, compile for debugging as well.
1163 if (outer_info->HasDebugCode()) info.MarkAsDebug();
1164 Debug::RecordEvalCaller(script); 1202 Debug::RecordEvalCaller(script);
1165 1203
1166 shared_info = CompileToplevel(&info); 1204 shared_info = CompileToplevel(&info);
1167 1205
1168 if (shared_info.is_null()) { 1206 if (shared_info.is_null()) {
1169 return MaybeHandle<JSFunction>(); 1207 return MaybeHandle<JSFunction>();
1170 } else { 1208 } else {
1171 // Explicitly disable optimization for eval code. We're not yet prepared 1209 // Explicitly disable optimization for eval code. We're not yet prepared
1172 // to handle eval-code in the optimizing compiler. 1210 // to handle eval-code in the optimizing compiler.
1173 if (restriction != ONLY_SINGLE_FUNCTION_LITERAL) { 1211 if (restriction != ONLY_SINGLE_FUNCTION_LITERAL) {
1174 shared_info->DisableOptimization(kEval); 1212 shared_info->DisableOptimization(kEval);
1175 } 1213 }
1176 1214
1177 // If caller is strict mode, the result must be in strict mode as well. 1215 // If caller is strict mode, the result must be in strict mode as well.
1178 DCHECK(is_sloppy(language_mode) || 1216 DCHECK(is_sloppy(language_mode) ||
1179 is_strict(shared_info->language_mode())); 1217 is_strict(shared_info->language_mode()));
1180 compilation_cache->PutEval(source, outer_info, context, shared_info, 1218 compilation_cache->PutEval(source, outer_info, context, shared_info,
1181 line_offset); 1219 line_offset);
1182 } 1220 }
1183 } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) { 1221 } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) {
1184 shared_info->ResetForNewContext(isolate->heap()->global_ic_age()); 1222 shared_info->ResetForNewContext(isolate->heap()->global_ic_age());
1185 } 1223 }
1186 1224
1187 return isolate->factory()->NewFunctionFromSharedFunctionInfo( 1225 Handle<JSFunction> result =
1188 shared_info, context, NOT_TENURED); 1226 isolate->factory()->NewFunctionFromSharedFunctionInfo(
1227 shared_info, context, NOT_TENURED);
1228
1229 // OnAfterCompile has to be called after we create the JSFunction, which we
1230 // may require to recompile the eval for debugging, if we find a function
1231 // that contains break points in the eval script.
1232 isolate->debug()->OnAfterCompile(script);
1233
1234 return result;
1189 } 1235 }
1190 1236
1191 1237
1192 Handle<SharedFunctionInfo> Compiler::CompileScript( 1238 Handle<SharedFunctionInfo> Compiler::CompileScript(
1193 Handle<String> source, Handle<Object> script_name, int line_offset, 1239 Handle<String> source, Handle<Object> script_name, int line_offset,
1194 int column_offset, ScriptOriginOptions resource_options, 1240 int column_offset, ScriptOriginOptions resource_options,
1195 Handle<Object> source_map_url, Handle<Context> context, 1241 Handle<Object> source_map_url, Handle<Context> context,
1196 v8::Extension* extension, ScriptData** cached_data, 1242 v8::Extension* extension, ScriptData** cached_data,
1197 ScriptCompiler::CompileOptions compile_options, NativesFlag natives, 1243 ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
1198 bool is_module) { 1244 bool is_module) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 HistogramTimerScope histogram_timer( 1346 HistogramTimerScope histogram_timer(
1301 isolate->counters()->compile_serialize()); 1347 isolate->counters()->compile_serialize());
1302 *cached_data = CodeSerializer::Serialize(isolate, result, source); 1348 *cached_data = CodeSerializer::Serialize(isolate, result, source);
1303 if (FLAG_profile_deserialization) { 1349 if (FLAG_profile_deserialization) {
1304 PrintF("[Compiling and serializing took %0.3f ms]\n", 1350 PrintF("[Compiling and serializing took %0.3f ms]\n",
1305 timer.Elapsed().InMillisecondsF()); 1351 timer.Elapsed().InMillisecondsF());
1306 } 1352 }
1307 } 1353 }
1308 } 1354 }
1309 1355
1310 if (result.is_null()) isolate->ReportPendingMessages(); 1356 if (result.is_null()) {
1357 isolate->ReportPendingMessages();
1358 } else {
1359 isolate->debug()->OnAfterCompile(script);
1360 }
1311 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { 1361 } else if (result->ic_age() != isolate->heap()->global_ic_age()) {
1312 result->ResetForNewContext(isolate->heap()->global_ic_age()); 1362 result->ResetForNewContext(isolate->heap()->global_ic_age());
1313 } 1363 }
1314 return result; 1364 return result;
1315 } 1365 }
1316 1366
1317 1367
1318 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( 1368 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript(
1319 Handle<Script> script, ParseInfo* parse_info, int source_length) { 1369 Handle<Script> script, ParseInfo* parse_info, int source_length) {
1320 Isolate* isolate = script->GetIsolate(); 1370 Isolate* isolate = script->GetIsolate();
1321 // TODO(titzer): increment the counters in caller. 1371 // TODO(titzer): increment the counters in caller.
1322 isolate->counters()->total_load_size()->Increment(source_length); 1372 isolate->counters()->total_load_size()->Increment(source_length);
1323 isolate->counters()->total_compile_size()->Increment(source_length); 1373 isolate->counters()->total_compile_size()->Increment(source_length);
1324 1374
1325 LanguageMode language_mode = 1375 LanguageMode language_mode =
1326 construct_language_mode(FLAG_use_strict, FLAG_use_strong); 1376 construct_language_mode(FLAG_use_strict, FLAG_use_strong);
1327 parse_info->set_language_mode( 1377 parse_info->set_language_mode(
1328 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); 1378 static_cast<LanguageMode>(parse_info->language_mode() | language_mode));
1329 1379
1330 CompilationInfo compile_info(parse_info); 1380 CompilationInfo compile_info(parse_info);
1331 1381
1332 // If compiling for debugging, parse eagerly from scratch. 1382 // If compiling for debugging, parse eagerly from scratch.
1333 if (compile_info.is_debug()) parse_info->set_literal(NULL); 1383 if (compile_info.is_debug()) parse_info->set_literal(NULL);
1334 1384
1335 return CompileToplevel(&compile_info); 1385 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info);
1386 if (!result.is_null()) isolate->debug()->OnAfterCompile(script);
1387 return result;
1336 } 1388 }
1337 1389
1338 1390
1339 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( 1391 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
1340 FunctionLiteral* literal, Handle<Script> script, 1392 FunctionLiteral* literal, Handle<Script> script,
1341 CompilationInfo* outer_info) { 1393 CompilationInfo* outer_info) {
1342 // Precondition: code has been parsed and scopes have been analyzed. 1394 // Precondition: code has been parsed and scopes have been analyzed.
1343 Isolate* isolate = outer_info->isolate(); 1395 Isolate* isolate = outer_info->isolate();
1344 MaybeHandle<SharedFunctionInfo> maybe_existing; 1396 MaybeHandle<SharedFunctionInfo> maybe_existing;
1345 if (outer_info->is_first_compile()) { 1397 if (outer_info->is_first_compile()) {
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 1670
1619 1671
1620 #if DEBUG 1672 #if DEBUG
1621 void CompilationInfo::PrintAstForTesting() { 1673 void CompilationInfo::PrintAstForTesting() {
1622 PrintF("--- Source from AST ---\n%s\n", 1674 PrintF("--- Source from AST ---\n%s\n",
1623 PrettyPrinter(isolate(), zone()).PrintProgram(function())); 1675 PrettyPrinter(isolate(), zone()).PrintProgram(function()));
1624 } 1676 }
1625 #endif 1677 #endif
1626 } // namespace internal 1678 } // namespace internal
1627 } // namespace v8 1679 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698