| OLD | NEW |
| 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 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 DartEntry::InvokeNoSuchMethod(receiver, | 1238 DartEntry::InvokeNoSuchMethod(receiver, |
| 1239 original_function_name, | 1239 original_function_name, |
| 1240 orig_arguments, | 1240 orig_arguments, |
| 1241 orig_arguments_desc)); | 1241 orig_arguments_desc)); |
| 1242 CheckResultError(result); | 1242 CheckResultError(result); |
| 1243 arguments.SetReturn(result); | 1243 arguments.SetReturn(result); |
| 1244 } | 1244 } |
| 1245 | 1245 |
| 1246 | 1246 |
| 1247 static bool CanOptimizeFunction(const Function& function, Thread* thread) { | 1247 static bool CanOptimizeFunction(const Function& function, Thread* thread) { |
| 1248 const intptr_t kLowInvocationCount = -100000000; | |
| 1249 Isolate* isolate = thread->isolate(); | 1248 Isolate* isolate = thread->isolate(); |
| 1250 if (isolate->debugger()->IsStepping() || | 1249 if (isolate->debugger()->IsStepping() || |
| 1251 isolate->debugger()->HasBreakpoint(function, thread->zone())) { | 1250 isolate->debugger()->HasBreakpoint(function, thread->zone())) { |
| 1252 // We cannot set breakpoints and single step in optimized code, | 1251 // We cannot set breakpoints and single step in optimized code, |
| 1253 // so do not optimize the function. | 1252 // so do not optimize the function. |
| 1254 function.set_usage_counter(0); | 1253 function.set_usage_counter(0); |
| 1255 return false; | 1254 return false; |
| 1256 } | 1255 } |
| 1257 if (function.deoptimization_counter() >= | 1256 if (function.deoptimization_counter() >= |
| 1258 FLAG_max_deoptimization_counter_threshold) { | 1257 FLAG_max_deoptimization_counter_threshold) { |
| 1259 if (FLAG_trace_failed_optimization_attempts || | 1258 if (FLAG_trace_failed_optimization_attempts || |
| 1260 FLAG_stop_on_excessive_deoptimization) { | 1259 FLAG_stop_on_excessive_deoptimization) { |
| 1261 OS::PrintErr("Too Many Deoptimizations: %s\n", | 1260 THR_Print("Too many deoptimizations: %s\n", |
| 1262 function.ToFullyQualifiedCString()); | 1261 function.ToFullyQualifiedCString()); |
| 1263 if (FLAG_stop_on_excessive_deoptimization) { | 1262 if (FLAG_stop_on_excessive_deoptimization) { |
| 1264 FATAL("Stop on excessive deoptimization"); | 1263 FATAL("Stop on excessive deoptimization"); |
| 1265 } | 1264 } |
| 1266 } | 1265 } |
| 1267 // TODO(srdjan): Investigate excessive deoptimization. | 1266 // The function will not be optimized any longer. This situation can occur |
| 1268 function.set_usage_counter(kLowInvocationCount); | 1267 // mostly with small optimization counter thresholds. |
| 1268 function.SetIsOptimizable(false); |
| 1269 function.set_usage_counter(INT_MIN); |
| 1269 return false; | 1270 return false; |
| 1270 } | 1271 } |
| 1271 if (FLAG_optimization_filter != NULL) { | 1272 if (FLAG_optimization_filter != NULL) { |
| 1272 // FLAG_optimization_filter is a comma-separated list of strings that are | 1273 // FLAG_optimization_filter is a comma-separated list of strings that are |
| 1273 // matched against the fully-qualified function name. | 1274 // matched against the fully-qualified function name. |
| 1274 char* save_ptr; // Needed for strtok_r. | 1275 char* save_ptr; // Needed for strtok_r. |
| 1275 const char* function_name = function.ToFullyQualifiedCString(); | 1276 const char* function_name = function.ToFullyQualifiedCString(); |
| 1276 intptr_t len = strlen(FLAG_optimization_filter) + 1; // Length with \0. | 1277 intptr_t len = strlen(FLAG_optimization_filter) + 1; // Length with \0. |
| 1277 char* filter = new char[len]; | 1278 char* filter = new char[len]; |
| 1278 strncpy(filter, FLAG_optimization_filter, len); // strtok modifies arg 1. | 1279 strncpy(filter, FLAG_optimization_filter, len); // strtok modifies arg 1. |
| 1279 char* token = strtok_r(filter, ",", &save_ptr); | 1280 char* token = strtok_r(filter, ",", &save_ptr); |
| 1280 bool found = false; | 1281 bool found = false; |
| 1281 while (token != NULL) { | 1282 while (token != NULL) { |
| 1282 if (strstr(function_name, token) != NULL) { | 1283 if (strstr(function_name, token) != NULL) { |
| 1283 found = true; | 1284 found = true; |
| 1284 break; | 1285 break; |
| 1285 } | 1286 } |
| 1286 token = strtok_r(NULL, ",", &save_ptr); | 1287 token = strtok_r(NULL, ",", &save_ptr); |
| 1287 } | 1288 } |
| 1288 delete[] filter; | 1289 delete[] filter; |
| 1289 if (!found) { | 1290 if (!found) { |
| 1290 function.set_usage_counter(kLowInvocationCount); | 1291 function.set_usage_counter(INT_MIN); |
| 1291 return false; | 1292 return false; |
| 1292 } | 1293 } |
| 1293 } | 1294 } |
| 1294 if (!function.IsOptimizable()) { | 1295 if (!function.IsOptimizable()) { |
| 1296 // Huge methods (code size above --huge_method_cutoff_in_code_size) become |
| 1297 // non-optimizable only after the code has been generated. |
| 1295 if (FLAG_trace_failed_optimization_attempts) { | 1298 if (FLAG_trace_failed_optimization_attempts) { |
| 1296 OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString()); | 1299 THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString()); |
| 1297 } | 1300 } |
| 1298 // TODO(5442338): Abort as this should not happen. | 1301 function.set_usage_counter(INT_MIN); |
| 1299 function.set_usage_counter(kLowInvocationCount); | |
| 1300 return false; | 1302 return false; |
| 1301 } | 1303 } |
| 1302 return true; | 1304 return true; |
| 1303 } | 1305 } |
| 1304 | 1306 |
| 1305 | 1307 |
| 1306 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1308 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
| 1307 #if defined(USING_SIMULATOR) | 1309 #if defined(USING_SIMULATOR) |
| 1308 uword stack_pos = Simulator::Current()->get_register(SPREG); | 1310 uword stack_pos = Simulator::Current()->get_register(SPREG); |
| 1309 #else | 1311 #else |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 1891 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
| 1890 const TypedData& new_data = | 1892 const TypedData& new_data = |
| 1891 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 1893 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
| 1892 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 1894 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
| 1893 typed_data_cell.SetAt(0, new_data); | 1895 typed_data_cell.SetAt(0, new_data); |
| 1894 arguments.SetReturn(new_data); | 1896 arguments.SetReturn(new_data); |
| 1895 } | 1897 } |
| 1896 | 1898 |
| 1897 | 1899 |
| 1898 } // namespace dart | 1900 } // namespace dart |
| OLD | NEW |