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

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

Issue 1884213004: Fix a crash in debugger, add flag --stress-test-background-compilation, add asserts. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 | « no previous file | runtime/vm/compiler.h » ('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) 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"
(...skipping 13 matching lines...) Expand all
24 #include "vm/symbols.h" 24 #include "vm/symbols.h"
25 #include "vm/thread_registry.h" 25 #include "vm/thread_registry.h"
26 #include "vm/verifier.h" 26 #include "vm/verifier.h"
27 27
28 namespace dart { 28 namespace dart {
29 29
30 DEFINE_FLAG(int, max_subtype_cache_entries, 100, 30 DEFINE_FLAG(int, max_subtype_cache_entries, 100,
31 "Maximum number of subtype cache entries (number of checks cached)."); 31 "Maximum number of subtype cache entries (number of checks cached).");
32 DEFINE_FLAG(int, regexp_optimization_counter_threshold, 1000, 32 DEFINE_FLAG(int, regexp_optimization_counter_threshold, 1000,
33 "RegExp's usage-counter value before it is optimized, -1 means never"); 33 "RegExp's usage-counter value before it is optimized, -1 means never");
34 DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function");
35 DEFINE_FLAG(int, reoptimization_counter_threshold, 4000, 34 DEFINE_FLAG(int, reoptimization_counter_threshold, 4000,
36 "Counter threshold before a function gets reoptimized."); 35 "Counter threshold before a function gets reoptimized.");
37 DEFINE_FLAG(bool, stop_on_excessive_deoptimization, false,
38 "Debugging: stops program if deoptimizing same function too often");
39 DEFINE_FLAG(bool, trace_deoptimization, false, "Trace deoptimization"); 36 DEFINE_FLAG(bool, trace_deoptimization, false, "Trace deoptimization");
40 DEFINE_FLAG(bool, trace_deoptimization_verbose, false, 37 DEFINE_FLAG(bool, trace_deoptimization_verbose, false,
41 "Trace deoptimization verbose"); 38 "Trace deoptimization verbose");
42 DEFINE_FLAG(bool, trace_failed_optimization_attempts, false,
43 "Traces all failed optimization attempts");
44 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); 39 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling");
45 DEFINE_FLAG(bool, trace_ic_miss_in_optimized, false, 40 DEFINE_FLAG(bool, trace_ic_miss_in_optimized, false,
46 "Trace IC miss in optimized code"); 41 "Trace IC miss in optimized code");
47 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, 42 DEFINE_FLAG(bool, trace_optimized_ic_calls, false,
48 "Trace IC calls in optimized code."); 43 "Trace IC calls in optimized code.");
49 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); 44 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
50 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); 45 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
51 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks."); 46 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
52 47
53 DECLARE_FLAG(int, max_deoptimization_counter_threshold); 48 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 const Object& result = Object::Handle( 1183 const Object& result = Object::Handle(
1189 DartEntry::InvokeNoSuchMethod(receiver, 1184 DartEntry::InvokeNoSuchMethod(receiver,
1190 original_function_name, 1185 original_function_name,
1191 orig_arguments, 1186 orig_arguments,
1192 orig_arguments_desc)); 1187 orig_arguments_desc));
1193 CheckResultError(result); 1188 CheckResultError(result);
1194 arguments.SetReturn(result); 1189 arguments.SetReturn(result);
1195 } 1190 }
1196 1191
1197 1192
1198 static bool CanOptimizeFunction(const Function& function, Thread* thread) {
1199 if (FLAG_support_debugger) {
1200 Isolate* isolate = thread->isolate();
1201 if (isolate->debugger()->IsStepping() ||
1202 isolate->debugger()->HasBreakpoint(function, thread->zone())) {
1203 // We cannot set breakpoints and single step in optimized code,
1204 // so do not optimize the function.
1205 function.set_usage_counter(0);
1206 return false;
1207 }
1208 }
1209 if (function.deoptimization_counter() >=
1210 FLAG_max_deoptimization_counter_threshold) {
1211 if (FLAG_trace_failed_optimization_attempts ||
1212 FLAG_stop_on_excessive_deoptimization) {
1213 THR_Print("Too many deoptimizations: %s\n",
1214 function.ToFullyQualifiedCString());
1215 if (FLAG_stop_on_excessive_deoptimization) {
1216 FATAL("Stop on excessive deoptimization");
1217 }
1218 }
1219 // The function will not be optimized any longer. This situation can occur
1220 // mostly with small optimization counter thresholds.
1221 function.SetIsOptimizable(false);
1222 function.set_usage_counter(INT_MIN);
1223 return false;
1224 }
1225 if (FLAG_optimization_filter != NULL) {
1226 // FLAG_optimization_filter is a comma-separated list of strings that are
1227 // matched against the fully-qualified function name.
1228 char* save_ptr; // Needed for strtok_r.
1229 const char* function_name = function.ToFullyQualifiedCString();
1230 intptr_t len = strlen(FLAG_optimization_filter) + 1; // Length with \0.
1231 char* filter = new char[len];
1232 strncpy(filter, FLAG_optimization_filter, len); // strtok modifies arg 1.
1233 char* token = strtok_r(filter, ",", &save_ptr);
1234 bool found = false;
1235 while (token != NULL) {
1236 if (strstr(function_name, token) != NULL) {
1237 found = true;
1238 break;
1239 }
1240 token = strtok_r(NULL, ",", &save_ptr);
1241 }
1242 delete[] filter;
1243 if (!found) {
1244 function.set_usage_counter(INT_MIN);
1245 return false;
1246 }
1247 }
1248 if (!function.IsOptimizable()) {
1249 // Huge methods (code size above --huge_method_cutoff_in_code_size) become
1250 // non-optimizable only after the code has been generated.
1251 if (FLAG_trace_failed_optimization_attempts) {
1252 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString());
1253 }
1254 function.set_usage_counter(INT_MIN);
1255 return false;
1256 }
1257 return true;
1258 }
1259
1260
1261 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { 1193 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
1262 #if defined(USING_SIMULATOR) 1194 #if defined(USING_SIMULATOR)
1263 uword stack_pos = Simulator::Current()->get_register(SPREG); 1195 uword stack_pos = Simulator::Current()->get_register(SPREG);
1264 #else 1196 #else
1265 uword stack_pos = Thread::GetCurrentStackPointer(); 1197 uword stack_pos = Thread::GetCurrentStackPointer();
1266 #endif 1198 #endif
1267 // Always clear the stack overflow flags. They are meant for this 1199 // Always clear the stack overflow flags. They are meant for this
1268 // particular stack overflow runtime call and are not meant to 1200 // particular stack overflow runtime call and are not meant to
1269 // persist. 1201 // persist.
1270 uword stack_overflow_flags = thread->GetAndClearStackOverflowFlags(); 1202 uword stack_overflow_flags = thread->GetAndClearStackOverflowFlags();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 ASSERT(frame != NULL); 1289 ASSERT(frame != NULL);
1358 const Code& code = Code::ZoneHandle(frame->LookupDartCode()); 1290 const Code& code = Code::ZoneHandle(frame->LookupDartCode());
1359 ASSERT(!code.IsNull()); 1291 ASSERT(!code.IsNull());
1360 const Function& function = Function::Handle(code.function()); 1292 const Function& function = Function::Handle(code.function());
1361 ASSERT(!function.IsNull()); 1293 ASSERT(!function.IsNull());
1362 // Since the code is referenced from the frame and the ZoneHandle, 1294 // Since the code is referenced from the frame and the ZoneHandle,
1363 // it cannot have been removed from the function. 1295 // it cannot have been removed from the function.
1364 ASSERT(function.HasCode()); 1296 ASSERT(function.HasCode());
1365 // Don't do OSR on intrinsified functions: The intrinsic code expects to be 1297 // Don't do OSR on intrinsified functions: The intrinsic code expects to be
1366 // called like a regular function and can't be entered via OSR. 1298 // called like a regular function and can't be entered via OSR.
1367 if (!CanOptimizeFunction(function, thread) || function.is_intrinsic()) { 1299 if (!Compiler::CanOptimizeFunction(thread, function) ||
1300 function.is_intrinsic()) {
1368 return; 1301 return;
1369 } 1302 }
1370 1303
1371 // The unoptimized code is on the stack and should never be detached from 1304 // The unoptimized code is on the stack and should never be detached from
1372 // the function at this point. 1305 // the function at this point.
1373 ASSERT(function.unoptimized_code() != Object::null()); 1306 ASSERT(function.unoptimized_code() != Object::null());
1374 intptr_t osr_id = 1307 intptr_t osr_id =
1375 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); 1308 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
1376 ASSERT(osr_id != Compiler::kNoOSRDeoptId); 1309 ASSERT(osr_id != Compiler::kNoOSRDeoptId);
1377 if (FLAG_trace_osr) { 1310 if (FLAG_trace_osr) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 // This is called from function that needs to be optimized. 1360 // This is called from function that needs to be optimized.
1428 // The requesting function can be already optimized (reoptimization). 1361 // The requesting function can be already optimized (reoptimization).
1429 // Returns the Code object where to continue execution. 1362 // Returns the Code object where to continue execution.
1430 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { 1363 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
1431 #if !defined(DART_PRECOMPILED_RUNTIME) 1364 #if !defined(DART_PRECOMPILED_RUNTIME)
1432 const Function& function = Function::CheckedHandle(zone, 1365 const Function& function = Function::CheckedHandle(zone,
1433 arguments.ArgAt(0)); 1366 arguments.ArgAt(0));
1434 ASSERT(!function.IsNull()); 1367 ASSERT(!function.IsNull());
1435 ASSERT(function.HasCode()); 1368 ASSERT(function.HasCode());
1436 1369
1437 if (CanOptimizeFunction(function, thread)) { 1370 if (Compiler::CanOptimizeFunction(thread, function)) {
1438 if (FLAG_background_compilation) { 1371 if (FLAG_background_compilation) {
1439 Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField()); 1372 Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField());
1440 while (!field.IsNull()) { 1373 while (!field.IsNull()) {
1441 if (FLAG_trace_optimization || FLAG_trace_field_guards) { 1374 if (FLAG_trace_optimization || FLAG_trace_field_guards) {
1442 THR_Print("Lazy disabling unboxing of %s\n", field.ToCString()); 1375 THR_Print("Lazy disabling unboxing of %s\n", field.ToCString());
1443 } 1376 }
1444 field.set_is_unboxing_candidate(false); 1377 field.set_is_unboxing_candidate(false);
1445 field.DeoptimizeDependentCode(); 1378 field.DeoptimizeDependentCode();
1446 // Get next field. 1379 // Get next field.
1447 field = isolate->GetDeoptimizingBoxedField(); 1380 field = isolate->GetDeoptimizingBoxedField();
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1885 const intptr_t elm_size = old_data.ElementSizeInBytes(); 1818 const intptr_t elm_size = old_data.ElementSizeInBytes();
1886 const TypedData& new_data = 1819 const TypedData& new_data =
1887 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 1820 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
1888 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 1821 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
1889 typed_data_cell.SetAt(0, new_data); 1822 typed_data_cell.SetAt(0, new_data);
1890 arguments.SetReturn(new_data); 1823 arguments.SetReturn(new_data);
1891 } 1824 }
1892 1825
1893 1826
1894 } // namespace dart 1827 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698