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

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

Issue 1390153004: Move deopt_id and related helpers/definitions from Isolate to Thread (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/block_scheduler.h" 10 #include "vm/block_scheduler.h"
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // We may reattempt compilation if the function needs to be assembled using 395 // We may reattempt compilation if the function needs to be assembled using
396 // far branches on ARM and MIPS. In the else branch of the setjmp call, 396 // far branches on ARM and MIPS. In the else branch of the setjmp call,
397 // done is set to false, and use_far_branches is set to true if there is a 397 // done is set to false, and use_far_branches is set to true if there is a
398 // longjmp from the ARM or MIPS assemblers. In all other paths through this 398 // longjmp from the ARM or MIPS assemblers. In all other paths through this
399 // while loop, done is set to true. use_far_branches is always false on ia32 399 // while loop, done is set to true. use_far_branches is always false on ia32
400 // and x64. 400 // and x64.
401 bool done = false; 401 bool done = false;
402 // volatile because the variable may be clobbered by a longjmp. 402 // volatile because the variable may be clobbered by a longjmp.
403 volatile bool use_far_branches = false; 403 volatile bool use_far_branches = false;
404 while (!done) { 404 while (!done) {
405 const intptr_t prev_deopt_id = isolate->deopt_id(); 405 const intptr_t prev_deopt_id = thread->deopt_id();
406 isolate->set_deopt_id(0); 406 thread->set_deopt_id(0);
407 LongJumpScope jump; 407 LongJumpScope jump;
408 if (setjmp(*jump.Set()) == 0) { 408 if (setjmp(*jump.Set()) == 0) {
409 FlowGraph* flow_graph = NULL; 409 FlowGraph* flow_graph = NULL;
410 410
411 // Class hierarchy analysis is registered with the isolate in the 411 // Class hierarchy analysis is registered with the isolate in the
412 // constructor and unregisters itself upon destruction. 412 // constructor and unregisters itself upon destruction.
413 CHA cha(thread); 413 CHA cha(thread);
414 414
415 // TimerScope needs an isolate to be properly terminated in case of a 415 // TimerScope needs an isolate to be properly terminated in case of a
416 // LongJump. 416 // LongJump.
(...skipping 22 matching lines...) Expand all
439 *ic_data_array, 439 *ic_data_array,
440 osr_id); 440 osr_id);
441 } 441 }
442 442
443 const bool print_flow_graph = 443 const bool print_flow_graph =
444 (FLAG_print_flow_graph || 444 (FLAG_print_flow_graph ||
445 (optimized && FLAG_print_flow_graph_optimized)) && 445 (optimized && FLAG_print_flow_graph_optimized)) &&
446 FlowGraphPrinter::ShouldPrint(function); 446 FlowGraphPrinter::ShouldPrint(function);
447 447
448 if (print_flow_graph) { 448 if (print_flow_graph) {
449 if (osr_id == Isolate::kNoDeoptId) { 449 if (osr_id == Thread::kNoDeoptId) {
450 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 450 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
451 } else { 451 } else {
452 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); 452 FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
453 } 453 }
454 } 454 }
455 455
456 BlockScheduler block_scheduler(flow_graph); 456 BlockScheduler block_scheduler(flow_graph);
457 const bool reorder_blocks = 457 const bool reorder_blocks =
458 FlowGraph::ShouldReorderBlocks(function, optimized); 458 FlowGraph::ShouldReorderBlocks(function, optimized);
459 if (reorder_blocks) { 459 if (reorder_blocks) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 graph_compiler.FinalizePcDescriptors(code); 750 graph_compiler.FinalizePcDescriptors(code);
751 code.set_deopt_info_array(deopt_info_array); 751 code.set_deopt_info_array(deopt_info_array);
752 752
753 graph_compiler.FinalizeStackmaps(code); 753 graph_compiler.FinalizeStackmaps(code);
754 graph_compiler.FinalizeVarDescriptors(code); 754 graph_compiler.FinalizeVarDescriptors(code);
755 graph_compiler.FinalizeExceptionHandlers(code); 755 graph_compiler.FinalizeExceptionHandlers(code);
756 graph_compiler.FinalizeStaticCallTargetsTable(code); 756 graph_compiler.FinalizeStaticCallTargetsTable(code);
757 757
758 if (optimized) { 758 if (optimized) {
759 // We may not have previous code if 'always_optimize' is set. 759 // We may not have previous code if 'always_optimize' is set.
760 if ((osr_id == Isolate::kNoDeoptId) && function.HasCode()) { 760 if ((osr_id == Thread::kNoDeoptId) && function.HasCode()) {
761 Code::Handle(function.CurrentCode()).DisableDartCode(); 761 Code::Handle(function.CurrentCode()).DisableDartCode();
762 } 762 }
763 function.AttachCode(code); 763 function.AttachCode(code);
764 764
765 // Register code with the classes it depends on because of CHA. 765 // Register code with the classes it depends on because of CHA.
766 for (intptr_t i = 0; 766 for (intptr_t i = 0;
767 i < thread->cha()->leaf_classes().length(); 767 i < thread->cha()->leaf_classes().length();
768 ++i) { 768 ++i) {
769 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); 769 thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
770 } 770 }
(...skipping 17 matching lines...) Expand all
788 if (parsed_function->HasDeferredPrefixes()) { 788 if (parsed_function->HasDeferredPrefixes()) {
789 ASSERT(!FLAG_load_deferred_eagerly); 789 ASSERT(!FLAG_load_deferred_eagerly);
790 ZoneGrowableArray<const LibraryPrefix*>* prefixes = 790 ZoneGrowableArray<const LibraryPrefix*>* prefixes =
791 parsed_function->deferred_prefixes(); 791 parsed_function->deferred_prefixes();
792 for (intptr_t i = 0; i < prefixes->length(); i++) { 792 for (intptr_t i = 0; i < prefixes->length(); i++) {
793 (*prefixes)[i]->RegisterDependentCode(code); 793 (*prefixes)[i]->RegisterDependentCode(code);
794 } 794 }
795 } 795 }
796 } 796 }
797 // Mark that this isolate now has compiled code. 797 // Mark that this isolate now has compiled code.
798 isolate->set_has_compiled(true); 798 isolate->set_has_compiled_code(true);
799 // Exit the loop and the function with the correct result value. 799 // Exit the loop and the function with the correct result value.
800 is_compiled = true; 800 is_compiled = true;
801 done = true; 801 done = true;
802 } else { 802 } else {
803 // We bailed out or we encountered an error. 803 // We bailed out or we encountered an error.
804 const Error& error = Error::Handle( 804 const Error& error = Error::Handle(
805 isolate->object_store()->sticky_error()); 805 isolate->object_store()->sticky_error());
806 806
807 if (error.raw() == Object::branch_offset_error().raw()) { 807 if (error.raw() == Object::branch_offset_error().raw()) {
808 // Compilation failed due to an out of range branch offset in the 808 // Compilation failed due to an out of range branch offset in the
(...skipping 13 matching lines...) Expand all
822 } 822 }
823 823
824 // Clear the error if it was not a real error, but just a bailout. 824 // Clear the error if it was not a real error, but just a bailout.
825 if (error.IsLanguageError() && 825 if (error.IsLanguageError() &&
826 (LanguageError::Cast(error).kind() == Report::kBailout)) { 826 (LanguageError::Cast(error).kind() == Report::kBailout)) {
827 isolate->object_store()->clear_sticky_error(); 827 isolate->object_store()->clear_sticky_error();
828 } 828 }
829 is_compiled = false; 829 is_compiled = false;
830 } 830 }
831 // Reset global isolate state. 831 // Reset global isolate state.
832 isolate->set_deopt_id(prev_deopt_id); 832 thread->set_deopt_id(prev_deopt_id);
833 } 833 }
834 return is_compiled; 834 return is_compiled;
835 } 835 }
836 836
837 837
838 static void DisassembleCode(const Function& function, bool optimized) { 838 static void DisassembleCode(const Function& function, bool optimized) {
839 const char* function_fullname = function.ToFullyQualifiedCString(); 839 const char* function_fullname = function.ToFullyQualifiedCString();
840 THR_Print("Code for %sfunction '%s' {\n", 840 THR_Print("Code for %sfunction '%s' {\n",
841 optimized ? "optimized " : "", 841 optimized ? "optimized " : "",
842 function_fullname); 842 function_fullname);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 Isolate* const isolate = thread->isolate(); 1011 Isolate* const isolate = thread->isolate();
1012 StackZone stack_zone(thread); 1012 StackZone stack_zone(thread);
1013 Zone* const zone = stack_zone.GetZone(); 1013 Zone* const zone = stack_zone.GetZone();
1014 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); 1014 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
1015 per_compile_timer.Start(); 1015 per_compile_timer.Start();
1016 1016
1017 ParsedFunction* parsed_function = new(zone) ParsedFunction( 1017 ParsedFunction* parsed_function = new(zone) ParsedFunction(
1018 thread, Function::ZoneHandle(zone, function.raw())); 1018 thread, Function::ZoneHandle(zone, function.raw()));
1019 if (FLAG_trace_compiler) { 1019 if (FLAG_trace_compiler) {
1020 THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", 1020 THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
1021 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), 1021 (osr_id == Thread::kNoDeoptId ? "" : "osr "),
1022 (optimized ? "optimized " : ""), 1022 (optimized ? "optimized " : ""),
1023 function.ToFullyQualifiedCString(), 1023 function.ToFullyQualifiedCString(),
1024 function.token_pos(), 1024 function.token_pos(),
1025 (function.end_token_pos() - function.token_pos())); 1025 (function.end_token_pos() - function.token_pos()));
1026 } 1026 }
1027 INC_STAT(thread, num_functions_compiled, 1); 1027 INC_STAT(thread, num_functions_compiled, 1);
1028 if (optimized) { 1028 if (optimized) {
1029 INC_STAT(thread, num_functions_optimized, 1); 1029 INC_STAT(thread, num_functions_optimized, 1);
1030 } 1030 }
1031 { 1031 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 Function::KindToCString(function.kind())); 1113 Function::KindToCString(function.kind()));
1114 } 1114 }
1115 1115
1116 CompilationPipeline* pipeline = 1116 CompilationPipeline* pipeline =
1117 CompilationPipeline::New(thread->zone(), function); 1117 CompilationPipeline::New(thread->zone(), function);
1118 1118
1119 const bool optimized = 1119 const bool optimized =
1120 Compiler::always_optimize() && function.IsOptimizable(); 1120 Compiler::always_optimize() && function.IsOptimizable();
1121 1121
1122 return CompileFunctionHelper(pipeline, function, optimized, 1122 return CompileFunctionHelper(pipeline, function, optimized,
1123 Isolate::kNoDeoptId); 1123 Thread::kNoDeoptId);
1124 } 1124 }
1125 1125
1126 1126
1127 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, 1127 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
1128 const Function& function) { 1128 const Function& function) {
1129 if (function.unoptimized_code() != Object::null()) { 1129 if (function.unoptimized_code() != Object::null()) {
1130 return Error::null(); 1130 return Error::null();
1131 } 1131 }
1132 Code& original_code = Code::ZoneHandle(thread->zone()); 1132 Code& original_code = Code::ZoneHandle(thread->zone());
1133 if (function.HasCode()) { 1133 if (function.HasCode()) {
1134 original_code = function.CurrentCode(); 1134 original_code = function.CurrentCode();
1135 } 1135 }
1136 CompilationPipeline* pipeline = 1136 CompilationPipeline* pipeline =
1137 CompilationPipeline::New(thread->zone(), function); 1137 CompilationPipeline::New(thread->zone(), function);
1138 const Error& error = Error::Handle( 1138 const Error& error = Error::Handle(
1139 CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId)); 1139 CompileFunctionHelper(pipeline, function, false, Thread::kNoDeoptId));
1140 if (!error.IsNull()) { 1140 if (!error.IsNull()) {
1141 return error.raw(); 1141 return error.raw();
1142 } 1142 }
1143 // Since CompileFunctionHelper replaces the current code, re-attach the 1143 // Since CompileFunctionHelper replaces the current code, re-attach the
1144 // the original code if the function was already compiled. 1144 // the original code if the function was already compiled.
1145 if (!original_code.IsNull() && 1145 if (!original_code.IsNull() &&
1146 (original_code.raw() != function.CurrentCode())) { 1146 (original_code.raw() != function.CurrentCode())) {
1147 function.AttachCode(original_code); 1147 function.AttachCode(original_code);
1148 } 1148 }
1149 ASSERT(function.unoptimized_code() != Object::null()); 1149 ASSERT(function.unoptimized_code() != Object::null());
(...skipping 20 matching lines...) Expand all
1170 // This is only used from unit tests. 1170 // This is only used from unit tests.
1171 RawError* Compiler::CompileParsedFunction( 1171 RawError* Compiler::CompileParsedFunction(
1172 ParsedFunction* parsed_function) { 1172 ParsedFunction* parsed_function) {
1173 LongJumpScope jump; 1173 LongJumpScope jump;
1174 if (setjmp(*jump.Set()) == 0) { 1174 if (setjmp(*jump.Set()) == 0) {
1175 // Non-optimized code generator. 1175 // Non-optimized code generator.
1176 DartCompilationPipeline pipeline; 1176 DartCompilationPipeline pipeline;
1177 CompileParsedFunctionHelper(&pipeline, 1177 CompileParsedFunctionHelper(&pipeline,
1178 parsed_function, 1178 parsed_function,
1179 false, 1179 false,
1180 Isolate::kNoDeoptId); 1180 Thread::kNoDeoptId);
1181 if (FLAG_disassemble) { 1181 if (FLAG_disassemble) {
1182 DisassembleCode(parsed_function->function(), false); 1182 DisassembleCode(parsed_function->function(), false);
1183 } 1183 }
1184 return Error::null(); 1184 return Error::null();
1185 } else { 1185 } else {
1186 Isolate* const isolate = Isolate::Current(); 1186 Isolate* const isolate = Isolate::Current();
1187 Error& error = Error::Handle(); 1187 Error& error = Error::Handle();
1188 // We got an error during compilation. 1188 // We got an error during compilation.
1189 error = isolate->object_store()->sticky_error(); 1189 error = isolate->object_store()->sticky_error();
1190 isolate->object_store()->clear_sticky_error(); 1190 isolate->object_store()->clear_sticky_error();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 StackZone zone(thread); 1276 StackZone zone(thread);
1277 1277
1278 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); 1278 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field);
1279 1279
1280 parsed_function->AllocateVariables(); 1280 parsed_function->AllocateVariables();
1281 // Non-optimized code generator. 1281 // Non-optimized code generator.
1282 DartCompilationPipeline pipeline; 1282 DartCompilationPipeline pipeline;
1283 CompileParsedFunctionHelper(&pipeline, 1283 CompileParsedFunctionHelper(&pipeline,
1284 parsed_function, 1284 parsed_function,
1285 false, // optimized 1285 false, // optimized
1286 Isolate::kNoDeoptId); 1286 Thread::kNoDeoptId);
1287 1287
1288 const Function& initializer = parsed_function->function(); 1288 const Function& initializer = parsed_function->function();
1289 field.SetPrecompiledInitializer(initializer); 1289 field.SetPrecompiledInitializer(initializer);
1290 } 1290 }
1291 1291
1292 1292
1293 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { 1293 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
1294 ASSERT(field.is_static()); 1294 ASSERT(field.is_static());
1295 // The VM sets the field's value to transiton_sentinel prior to 1295 // The VM sets the field's value to transiton_sentinel prior to
1296 // evaluating the initializer value. 1296 // evaluating the initializer value.
(...skipping 10 matching lines...) Expand all
1307 StackZone zone(thread); 1307 StackZone zone(thread);
1308 ParsedFunction* parsed_function = 1308 ParsedFunction* parsed_function =
1309 Parser::ParseStaticFieldInitializer(field); 1309 Parser::ParseStaticFieldInitializer(field);
1310 1310
1311 parsed_function->AllocateVariables(); 1311 parsed_function->AllocateVariables();
1312 // Non-optimized code generator. 1312 // Non-optimized code generator.
1313 DartCompilationPipeline pipeline; 1313 DartCompilationPipeline pipeline;
1314 CompileParsedFunctionHelper(&pipeline, 1314 CompileParsedFunctionHelper(&pipeline,
1315 parsed_function, 1315 parsed_function,
1316 false, // optimized 1316 false, // optimized
1317 Isolate::kNoDeoptId); 1317 Thread::kNoDeoptId);
1318 initializer = parsed_function->function().raw(); 1318 initializer = parsed_function->function().raw();
1319 Code::Handle(initializer.unoptimized_code()).set_var_descriptors( 1319 Code::Handle(initializer.unoptimized_code()).set_var_descriptors(
1320 Object::empty_var_descriptors()); 1320 Object::empty_var_descriptors());
1321 } else { 1321 } else {
1322 initializer ^= field.PrecompiledInitializer(); 1322 initializer ^= field.PrecompiledInitializer();
1323 } 1323 }
1324 // Invoke the function to evaluate the expression. 1324 // Invoke the function to evaluate the expression.
1325 return DartEntry::InvokeFunction(initializer, Object::empty_array()); 1325 return DartEntry::InvokeFunction(initializer, Object::empty_array());
1326 } else { 1326 } else {
1327 Thread* const thread = Thread::Current(); 1327 Thread* const thread = Thread::Current();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); 1377 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp());
1378 fragment->scope()->AddVariable( 1378 fragment->scope()->AddVariable(
1379 parsed_function->current_context_var()); 1379 parsed_function->current_context_var());
1380 parsed_function->AllocateVariables(); 1380 parsed_function->AllocateVariables();
1381 1381
1382 // Non-optimized code generator. 1382 // Non-optimized code generator.
1383 DartCompilationPipeline pipeline; 1383 DartCompilationPipeline pipeline;
1384 CompileParsedFunctionHelper(&pipeline, 1384 CompileParsedFunctionHelper(&pipeline,
1385 parsed_function, 1385 parsed_function,
1386 false, 1386 false,
1387 Isolate::kNoDeoptId); 1387 Thread::kNoDeoptId);
1388 Code::Handle(func.unoptimized_code()).set_var_descriptors( 1388 Code::Handle(func.unoptimized_code()).set_var_descriptors(
1389 Object::empty_var_descriptors()); 1389 Object::empty_var_descriptors());
1390 1390
1391 const Object& result = PassiveObject::Handle( 1391 const Object& result = PassiveObject::Handle(
1392 DartEntry::InvokeFunction(func, Object::empty_array())); 1392 DartEntry::InvokeFunction(func, Object::empty_array()));
1393 return result.raw(); 1393 return result.raw();
1394 } else { 1394 } else {
1395 Thread* const thread = Thread::Current(); 1395 Thread* const thread = Thread::Current();
1396 Isolate* const isolate = thread->isolate(); 1396 Isolate* const isolate = thread->isolate();
1397 const Object& result = 1397 const Object& result =
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 isolate->current_zone(), GrowableObjectArray::New())); 1557 isolate->current_zone(), GrowableObjectArray::New()));
1558 start_task = true; 1558 start_task = true;
1559 } 1559 }
1560 } 1560 }
1561 if (start_task) { 1561 if (start_task) {
1562 Dart::thread_pool()->Run(isolate->background_compiler()); 1562 Dart::thread_pool()->Run(isolate->background_compiler());
1563 } 1563 }
1564 } 1564 }
1565 1565
1566 } // namespace dart 1566 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698