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

Side by Side Diff: runtime/vm/code_generator.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/debugger.h" 13 #include "vm/debugger.h"
14 #include "vm/deopt_instructions.h" 14 #include "vm/deopt_instructions.h"
15 #include "vm/exceptions.h" 15 #include "vm/exceptions.h"
16 #include "vm/flags.h" 16 #include "vm/flags.h"
17 #include "vm/object_store.h" 17 #include "vm/object_store.h"
18 #include "vm/message.h" 18 #include "vm/message.h"
19 #include "vm/message_handler.h" 19 #include "vm/message_handler.h"
20 #include "vm/parser.h" 20 #include "vm/parser.h"
21 #include "vm/resolver.h" 21 #include "vm/resolver.h"
22 #include "vm/runtime_entry.h" 22 #include "vm/runtime_entry.h"
23 #include "vm/service_isolate.h"
23 #include "vm/stack_frame.h" 24 #include "vm/stack_frame.h"
24 #include "vm/symbols.h" 25 #include "vm/symbols.h"
25 #include "vm/thread_registry.h" 26 #include "vm/thread_registry.h"
26 #include "vm/verifier.h" 27 #include "vm/verifier.h"
27 28
28 namespace dart { 29 namespace dart {
29 30
30 DEFINE_FLAG(int, max_subtype_cache_entries, 100, 31 DEFINE_FLAG(int, max_subtype_cache_entries, 100,
31 "Maximum number of subtype cache entries (number of checks cached)."); 32 "Maximum number of subtype cache entries (number of checks cached).");
32 DEFINE_FLAG(int, regexp_optimization_counter_threshold, 1000, 33 DEFINE_FLAG(int, regexp_optimization_counter_threshold, 1000,
(...skipping 20 matching lines...) Expand all
53 54
54 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); 55 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
55 56
56 DEFINE_FLAG(int, stacktrace_every, 0, 57 DEFINE_FLAG(int, stacktrace_every, 0,
57 "Compute debugger stacktrace on every N stack overflow checks"); 58 "Compute debugger stacktrace on every N stack overflow checks");
58 DEFINE_FLAG(charp, stacktrace_filter, NULL, 59 DEFINE_FLAG(charp, stacktrace_filter, NULL,
59 "Compute stacktrace in named function on stack overflow checks"); 60 "Compute stacktrace in named function on stack overflow checks");
60 DEFINE_FLAG(charp, deoptimize_filter, NULL, 61 DEFINE_FLAG(charp, deoptimize_filter, NULL,
61 "Deoptimize in named function on stack overflow checks"); 62 "Deoptimize in named function on stack overflow checks");
62 63
64 DECLARE_FLAG(int, reload_every);
65 DECLARE_FLAG(bool, reload_every_optimized);
66
63 #ifdef DEBUG 67 #ifdef DEBUG
64 DEFINE_FLAG(charp, gc_at_instance_allocation, NULL, 68 DEFINE_FLAG(charp, gc_at_instance_allocation, NULL,
65 "Perform a GC before allocation of instances of " 69 "Perform a GC before allocation of instances of "
66 "the specified class"); 70 "the specified class");
67 #endif 71 #endif
68 72
69 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { 73 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) {
70 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 74 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
71 const String& function_name = String::Handle(function.name()); 75 const String& function_name = String::Handle(function.name());
72 const String& class_name = 76 const String& class_name =
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 const Instance& exception = 1234 const Instance& exception =
1231 Instance::Handle(isolate->object_store()->stack_overflow()); 1235 Instance::Handle(isolate->object_store()->stack_overflow());
1232 Exceptions::Throw(thread, exception); 1236 Exceptions::Throw(thread, exception);
1233 UNREACHABLE(); 1237 UNREACHABLE();
1234 } 1238 }
1235 1239
1236 // The following code is used to stress test deoptimization and 1240 // The following code is used to stress test deoptimization and
1237 // debugger stack tracing. 1241 // debugger stack tracing.
1238 bool do_deopt = false; 1242 bool do_deopt = false;
1239 bool do_stacktrace = false; 1243 bool do_stacktrace = false;
1240 if ((FLAG_deoptimize_every > 0) || (FLAG_stacktrace_every > 0)) { 1244 bool do_reload = false;
1245 if ((FLAG_deoptimize_every > 0) ||
1246 (FLAG_stacktrace_every > 0) ||
1247 (FLAG_reload_every > 0)) {
1241 // TODO(turnidge): To make --deoptimize_every and 1248 // TODO(turnidge): To make --deoptimize_every and
1242 // --stacktrace-every faster we could move this increment/test to 1249 // --stacktrace-every faster we could move this increment/test to
1243 // the generated code. 1250 // the generated code.
1244 int32_t count = thread->IncrementAndGetStackOverflowCount(); 1251 int32_t count = thread->IncrementAndGetStackOverflowCount();
1245 if (FLAG_deoptimize_every > 0 && 1252 if (FLAG_deoptimize_every > 0 &&
1246 (count % FLAG_deoptimize_every) == 0) { 1253 (count % FLAG_deoptimize_every) == 0) {
1247 do_deopt = true; 1254 do_deopt = true;
1248 } 1255 }
1249 if (FLAG_stacktrace_every > 0 && 1256 if (FLAG_stacktrace_every > 0 &&
1250 (count % FLAG_stacktrace_every) == 0) { 1257 (count % FLAG_stacktrace_every) == 0) {
1251 do_stacktrace = true; 1258 do_stacktrace = true;
1252 } 1259 }
1260 if ((FLAG_reload_every > 0) &&
1261 (count % FLAG_reload_every) == 0) {
1262 do_reload = isolate->CanReload();
1263 }
1253 } 1264 }
1254 if ((FLAG_deoptimize_filter != NULL) || (FLAG_stacktrace_filter != NULL)) { 1265 if ((FLAG_deoptimize_filter != NULL) ||
1266 (FLAG_stacktrace_filter != NULL) ||
1267 FLAG_reload_every_optimized) {
1255 DartFrameIterator iterator; 1268 DartFrameIterator iterator;
1256 StackFrame* frame = iterator.NextFrame(); 1269 StackFrame* frame = iterator.NextFrame();
1257 ASSERT(frame != NULL); 1270 ASSERT(frame != NULL);
1258 const Code& code = Code::Handle(frame->LookupDartCode()); 1271 const Code& code = Code::Handle(frame->LookupDartCode());
1259 ASSERT(!code.IsNull()); 1272 ASSERT(!code.IsNull());
1260 const Function& function = Function::Handle(code.function()); 1273 const Function& function = Function::Handle(code.function());
1261 ASSERT(!function.IsNull()); 1274 ASSERT(!function.IsNull());
1262 const char* function_name = function.ToFullyQualifiedCString(); 1275 const char* function_name = function.ToFullyQualifiedCString();
1263 ASSERT(function_name != NULL); 1276 ASSERT(function_name != NULL);
1277 if (!code.is_optimized() && FLAG_reload_every_optimized) {
1278 // Don't do the reload if we aren't inside optimized code.
1279 do_reload = false;
1280 }
1264 if (code.is_optimized() && 1281 if (code.is_optimized() &&
1265 FLAG_deoptimize_filter != NULL && 1282 FLAG_deoptimize_filter != NULL &&
1266 strstr(function_name, FLAG_deoptimize_filter) != NULL) { 1283 strstr(function_name, FLAG_deoptimize_filter) != NULL) {
1267 OS::PrintErr("*** Forcing deoptimization (%s)\n", 1284 OS::PrintErr("*** Forcing deoptimization (%s)\n",
1268 function.ToFullyQualifiedCString()); 1285 function.ToFullyQualifiedCString());
1269 do_deopt = true; 1286 do_deopt = true;
1270 } 1287 }
1271 if (FLAG_stacktrace_filter != NULL && 1288 if (FLAG_stacktrace_filter != NULL &&
1272 strstr(function_name, FLAG_stacktrace_filter) != NULL) { 1289 strstr(function_name, FLAG_stacktrace_filter) != NULL) {
1273 OS::PrintErr("*** Computing stacktrace (%s)\n", 1290 OS::PrintErr("*** Computing stacktrace (%s)\n",
1274 function.ToFullyQualifiedCString()); 1291 function.ToFullyQualifiedCString());
1275 do_stacktrace = true; 1292 do_stacktrace = true;
1276 } 1293 }
1277 } 1294 }
1278 if (do_deopt) { 1295 if (do_deopt) {
1279 // TODO(turnidge): Consider using DeoptimizeAt instead. 1296 // TODO(turnidge): Consider using DeoptimizeAt instead.
1280 DeoptimizeFunctionsOnStack(); 1297 DeoptimizeFunctionsOnStack();
1281 } 1298 }
1299 if (do_reload) {
1300 NOT_IN_PRODUCT(isolate->OnStackReload();)
1301 }
1282 if (FLAG_support_debugger && do_stacktrace) { 1302 if (FLAG_support_debugger && do_stacktrace) {
1283 String& var_name = String::Handle(); 1303 String& var_name = String::Handle();
1284 Instance& var_value = Instance::Handle(); 1304 Instance& var_value = Instance::Handle();
1285 // Collecting the stack trace and accessing local variables 1305 // Collecting the stack trace and accessing local variables
1286 // of frames may trigger parsing of functions to compute 1306 // of frames may trigger parsing of functions to compute
1287 // variable descriptors of functions. Parsing may trigger 1307 // variable descriptors of functions. Parsing may trigger
1288 // code execution, e.g. to compute compile-time constants. Thus, 1308 // code execution, e.g. to compute compile-time constants. Thus,
1289 // disable FLAG_stacktrace_every during trace collection to prevent 1309 // disable FLAG_stacktrace_every during trace collection to prevent
1290 // recursive stack trace collection. 1310 // recursive stack trace collection.
1291 intptr_t saved_stacktrace_every = FLAG_stacktrace_every; 1311 intptr_t saved_stacktrace_every = FLAG_stacktrace_every;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 field.DeoptimizeDependentCode(); 1427 field.DeoptimizeDependentCode();
1408 // Get next field. 1428 // Get next field.
1409 field = isolate->GetDeoptimizingBoxedField(); 1429 field = isolate->GetDeoptimizingBoxedField();
1410 } 1430 }
1411 } 1431 }
1412 // TODO(srdjan): Fix background compilation of regular expressions. 1432 // TODO(srdjan): Fix background compilation of regular expressions.
1413 if (FLAG_background_compilation) { 1433 if (FLAG_background_compilation) {
1414 if (FLAG_enable_inlining_annotations) { 1434 if (FLAG_enable_inlining_annotations) {
1415 FATAL("Cannot enable inlining annotations and background compilation"); 1435 FATAL("Cannot enable inlining annotations and background compilation");
1416 } 1436 }
1417 if (FLAG_background_compilation_stop_alot) { 1437 if (!BackgroundCompiler::IsDisabled()) {
1418 BackgroundCompiler::Stop(isolate); 1438 if (FLAG_background_compilation_stop_alot) {
1439 BackgroundCompiler::Stop(isolate);
1440 }
1441 // Reduce the chance of triggering optimization while the function is
1442 // being optimized in the background. INT_MIN should ensure that it
1443 // takes long time to trigger optimization.
1444 // Note that the background compilation queue rejects duplicate entries.
1445 function.set_usage_counter(INT_MIN);
1446 BackgroundCompiler::EnsureInit(thread);
1447 ASSERT(isolate->background_compiler() != NULL);
1448 isolate->background_compiler()->CompileOptimized(function);
1449 // Continue in the same code.
1450 arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
1451 return;
1419 } 1452 }
1420 // Reduce the chance of triggering optimization while the function is
1421 // being optimized in the background. INT_MIN should ensure that it takes
1422 // long time to trigger optimization.
1423 // Note that the background compilation queue rejects duplicate entries.
1424 function.set_usage_counter(INT_MIN);
1425 BackgroundCompiler::EnsureInit(thread);
1426 ASSERT(isolate->background_compiler() != NULL);
1427 isolate->background_compiler()->CompileOptimized(function);
1428 // Continue in the same code.
1429 arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
1430 return;
1431 } 1453 }
1432 1454
1433 // Reset usage counter for reoptimization before calling optimizer to 1455 // Reset usage counter for reoptimization before calling optimizer to
1434 // prevent recursive triggering of function optimization. 1456 // prevent recursive triggering of function optimization.
1435 function.set_usage_counter(0); 1457 function.set_usage_counter(0);
1436 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) { 1458 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) {
1437 if (function.HasOptimizedCode()) { 1459 if (function.HasOptimizedCode()) {
1438 THR_Print("ReCompiling function: '%s' \n", 1460 THR_Print("ReCompiling function: '%s' \n",
1439 function.ToFullyQualifiedCString()); 1461 function.ToFullyQualifiedCString());
1440 } 1462 }
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 const intptr_t elm_size = old_data.ElementSizeInBytes(); 1872 const intptr_t elm_size = old_data.ElementSizeInBytes();
1851 const TypedData& new_data = 1873 const TypedData& new_data =
1852 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 1874 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
1853 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 1875 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
1854 typed_data_cell.SetAt(0, new_data); 1876 typed_data_cell.SetAt(0, new_data);
1855 arguments.SetReturn(new_data); 1877 arguments.SetReturn(new_data);
1856 } 1878 }
1857 1879
1858 1880
1859 } // namespace dart 1881 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698