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

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

Issue 982873004: Thread/Isolate refactoring: new(Isolate) -> new(Zone) (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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 | Annotate | Revision Log
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 67 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
68 DECLARE_FLAG(bool, trace_inlining_intervals); 68 DECLARE_FLAG(bool, trace_inlining_intervals);
69 DECLARE_FLAG(bool, trace_irregexp); 69 DECLARE_FLAG(bool, trace_irregexp);
70 DECLARE_FLAG(bool, trace_patching); 70 DECLARE_FLAG(bool, trace_patching);
71 71
72 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove 72 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
73 // separate helpers functions & `optimizing` args. 73 // separate helpers functions & `optimizing` args.
74 class CompilationPipeline : public ZoneAllocated { 74 class CompilationPipeline : public ZoneAllocated {
75 public: 75 public:
76 static CompilationPipeline* New(Isolate* isolate, const Function& function); 76 static CompilationPipeline* New(Zone* zone, const Function& function);
77 77
78 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; 78 virtual void ParseFunction(ParsedFunction* parsed_function) = 0;
79 virtual FlowGraph* BuildFlowGraph( 79 virtual FlowGraph* BuildFlowGraph(
80 ParsedFunction* parsed_function, 80 ParsedFunction* parsed_function,
81 const ZoneGrowableArray<const ICData*>& ic_data_array, 81 const ZoneGrowableArray<const ICData*>& ic_data_array,
82 intptr_t osr_id) = 0; 82 intptr_t osr_id,
83 Zone* zone) = 0;
Ivan Posva 2015/03/13 21:56:49 We generally pass Isolate* as the first parameter,
koda 2015/03/14 00:46:36 Done.
83 virtual void FinalizeCompilation() = 0; 84 virtual void FinalizeCompilation() = 0;
84 virtual ~CompilationPipeline() { } 85 virtual ~CompilationPipeline() { }
85 }; 86 };
86 87
87 88
88 class DartCompilationPipeline : public CompilationPipeline { 89 class DartCompilationPipeline : public CompilationPipeline {
89 public: 90 public:
90 virtual void ParseFunction(ParsedFunction* parsed_function) { 91 virtual void ParseFunction(ParsedFunction* parsed_function) {
91 Parser::ParseFunction(parsed_function); 92 Parser::ParseFunction(parsed_function);
92 parsed_function->AllocateVariables(); 93 parsed_function->AllocateVariables();
93 } 94 }
94 95
95 virtual FlowGraph* BuildFlowGraph( 96 virtual FlowGraph* BuildFlowGraph(
96 ParsedFunction* parsed_function, 97 ParsedFunction* parsed_function,
97 const ZoneGrowableArray<const ICData*>& ic_data_array, 98 const ZoneGrowableArray<const ICData*>& ic_data_array,
98 intptr_t osr_id) { 99 intptr_t osr_id,
100 Zone* zone) {
99 // Build the flow graph. 101 // Build the flow graph.
100 FlowGraphBuilder builder(*parsed_function, 102 FlowGraphBuilder builder(*parsed_function,
101 ic_data_array, 103 ic_data_array,
102 NULL, // NULL = not inlining. 104 NULL, // NULL = not inlining.
103 osr_id); 105 osr_id);
104 106
105 return builder.BuildGraph(); 107 return builder.BuildGraph();
106 } 108 }
107 109
108 virtual void FinalizeCompilation() { } 110 virtual void FinalizeCompilation() { }
109 }; 111 };
110 112
111 113
112 class IrregexpCompilationPipeline : public CompilationPipeline { 114 class IrregexpCompilationPipeline : public CompilationPipeline {
113 public: 115 public:
114 explicit IrregexpCompilationPipeline(Isolate* isolate) 116 IrregexpCompilationPipeline() : backtrack_goto_(NULL) { }
115 : backtrack_goto_(NULL),
116 isolate_(isolate) { }
117 117
118 virtual void ParseFunction(ParsedFunction* parsed_function) { 118 virtual void ParseFunction(ParsedFunction* parsed_function) {
119 RegExpParser::ParseFunction(parsed_function); 119 RegExpParser::ParseFunction(parsed_function);
120 // Variables are allocated after compilation. 120 // Variables are allocated after compilation.
121 } 121 }
122 122
123 virtual FlowGraph* BuildFlowGraph( 123 virtual FlowGraph* BuildFlowGraph(
124 ParsedFunction* parsed_function, 124 ParsedFunction* parsed_function,
125 const ZoneGrowableArray<const ICData*>& ic_data_array, 125 const ZoneGrowableArray<const ICData*>& ic_data_array,
126 intptr_t osr_id) { 126 intptr_t osr_id,
127 Zone* zone) {
127 // Compile to the dart IR. 128 // Compile to the dart IR.
128 RegExpEngine::CompilationResult result = 129 RegExpEngine::CompilationResult result =
129 RegExpEngine::Compile(parsed_function->regexp_compile_data(), 130 RegExpEngine::Compile(parsed_function->regexp_compile_data(),
130 parsed_function, 131 parsed_function,
131 ic_data_array); 132 ic_data_array);
132 backtrack_goto_ = result.backtrack_goto; 133 backtrack_goto_ = result.backtrack_goto;
133 134
134 // Allocate variables now that we know the number of locals. 135 // Allocate variables now that we know the number of locals.
135 parsed_function->AllocateIrregexpVariables(result.num_stack_locals); 136 parsed_function->AllocateIrregexpVariables(result.num_stack_locals);
136 137
137 // Build the flow graph. 138 // Build the flow graph.
138 FlowGraphBuilder builder(*parsed_function, 139 FlowGraphBuilder builder(*parsed_function,
139 ic_data_array, 140 ic_data_array,
140 NULL, // NULL = not inlining. 141 NULL, // NULL = not inlining.
141 osr_id); 142 osr_id);
142 143
143 return new(isolate_) FlowGraph(*parsed_function, 144 return new(zone) FlowGraph(*parsed_function,
144 result.graph_entry, 145 result.graph_entry,
145 result.num_blocks); 146 result.num_blocks);
146 } 147 }
147 148
148 virtual void FinalizeCompilation() { 149 virtual void FinalizeCompilation() {
149 backtrack_goto_->ComputeOffsetTable(isolate_); 150 backtrack_goto_->ComputeOffsetTable();
150 } 151 }
151 152
152 private: 153 private:
153 IndirectGotoInstr* backtrack_goto_; 154 IndirectGotoInstr* backtrack_goto_;
154 Isolate* isolate_; 155 Zone* zone_;
Ivan Posva 2015/03/13 21:56:49 Where is zone_ being set?
koda 2015/03/14 00:46:36 Removed (leftover from previous version).
155 }; 156 };
156 157
157 CompilationPipeline* CompilationPipeline::New(Isolate* isolate, 158 CompilationPipeline* CompilationPipeline::New(Zone* zone,
158 const Function& function) { 159 const Function& function) {
159 if (function.IsIrregexpFunction()) { 160 if (function.IsIrregexpFunction()) {
160 return new(isolate) IrregexpCompilationPipeline(isolate); 161 return new(zone) IrregexpCompilationPipeline();
161 } else { 162 } else {
162 return new(isolate) DartCompilationPipeline(); 163 return new(zone) DartCompilationPipeline();
163 } 164 }
164 } 165 }
165 166
166 167
167 // Compile a function. Should call only if the function has not been compiled. 168 // Compile a function. Should call only if the function has not been compiled.
168 // Arg0: function object. 169 // Arg0: function object.
169 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { 170 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
170 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); 171 const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
171 ASSERT(!function.HasCode()); 172 ASSERT(!function.HasCode());
172 const Error& error = Error::Handle(Compiler::CompileFunction(isolate, 173 const Error& error = Error::Handle(Compiler::CompileFunction(thread,
173 function)); 174 function));
174 if (!error.IsNull()) { 175 if (!error.IsNull()) {
175 Exceptions::PropagateError(error); 176 Exceptions::PropagateError(error);
176 } 177 }
177 } 178 }
178 179
179 180
180 RawError* Compiler::Compile(const Library& library, const Script& script) { 181 RawError* Compiler::Compile(const Library& library, const Script& script) {
181 Isolate* isolate = Isolate::Current(); 182 Isolate* isolate = Isolate::Current();
182 StackZone zone(isolate); 183 StackZone zone(isolate);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, 368 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
368 ParsedFunction* parsed_function, 369 ParsedFunction* parsed_function,
369 bool optimized, 370 bool optimized,
370 intptr_t osr_id) { 371 intptr_t osr_id) {
371 const Function& function = parsed_function->function(); 372 const Function& function = parsed_function->function();
372 if (optimized && !function.IsOptimizable()) { 373 if (optimized && !function.IsOptimizable()) {
373 return false; 374 return false;
374 } 375 }
375 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 376 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
376 bool is_compiled = false; 377 bool is_compiled = false;
377 Isolate* isolate = Isolate::Current(); 378 Thread* thread = Thread::Current();
379 Zone* zone = thread->zone();
380 Isolate* isolate = thread->isolate();
378 HANDLESCOPE(isolate); 381 HANDLESCOPE(isolate);
379 382
380 // We may reattempt compilation if the function needs to be assembled using 383 // We may reattempt compilation if the function needs to be assembled using
381 // far branches on ARM and MIPS. In the else branch of the setjmp call, 384 // far branches on ARM and MIPS. In the else branch of the setjmp call,
382 // done is set to false, and use_far_branches is set to true if there is a 385 // done is set to false, and use_far_branches is set to true if there is a
383 // longjmp from the ARM or MIPS assemblers. In all other paths through this 386 // longjmp from the ARM or MIPS assemblers. In all other paths through this
384 // while loop, done is set to true. use_far_branches is always false on ia32 387 // while loop, done is set to true. use_far_branches is always false on ia32
385 // and x64. 388 // and x64.
386 bool done = false; 389 bool done = false;
387 // volatile because the variable may be clobbered by a longjmp. 390 // volatile because the variable may be clobbered by a longjmp.
388 volatile bool use_far_branches = false; 391 volatile bool use_far_branches = false;
389 while (!done) { 392 while (!done) {
390 const intptr_t prev_deopt_id = isolate->deopt_id(); 393 const intptr_t prev_deopt_id = isolate->deopt_id();
391 isolate->set_deopt_id(0); 394 isolate->set_deopt_id(0);
392 LongJumpScope jump; 395 LongJumpScope jump;
393 if (setjmp(*jump.Set()) == 0) { 396 if (setjmp(*jump.Set()) == 0) {
394 FlowGraph* flow_graph = NULL; 397 FlowGraph* flow_graph = NULL;
395 398
396 // Class hierarchy analysis is registered with the isolate in the 399 // Class hierarchy analysis is registered with the isolate in the
397 // constructor and unregisters itself upon destruction. 400 // constructor and unregisters itself upon destruction.
398 CHA cha(isolate); 401 CHA cha(isolate);
399 402
400 // TimerScope needs an isolate to be properly terminated in case of a 403 // TimerScope needs an isolate to be properly terminated in case of a
401 // LongJump. 404 // LongJump.
402 { 405 {
403 TimerScope timer(FLAG_compiler_stats, 406 TimerScope timer(FLAG_compiler_stats,
404 &CompilerStats::graphbuilder_timer, 407 &CompilerStats::graphbuilder_timer,
405 isolate); 408 isolate);
406 ZoneGrowableArray<const ICData*>* ic_data_array = 409 ZoneGrowableArray<const ICData*>* ic_data_array =
407 new(isolate) ZoneGrowableArray<const ICData*>(); 410 new(zone) ZoneGrowableArray<const ICData*>();
408 if (optimized) { 411 if (optimized) {
409 ASSERT(function.HasCode()); 412 ASSERT(function.HasCode());
410 // Extract type feedback before the graph is built, as the graph 413 // Extract type feedback before the graph is built, as the graph
411 // builder uses it to attach it to nodes. 414 // builder uses it to attach it to nodes.
412 ASSERT(function.deoptimization_counter() < 415 ASSERT(function.deoptimization_counter() <
413 FLAG_deoptimization_counter_threshold); 416 FLAG_deoptimization_counter_threshold);
414 function.RestoreICDataMap(ic_data_array); 417 function.RestoreICDataMap(ic_data_array);
415 if (FLAG_print_ic_data_map) { 418 if (FLAG_print_ic_data_map) {
416 for (intptr_t i = 0; i < ic_data_array->length(); i++) { 419 for (intptr_t i = 0; i < ic_data_array->length(); i++) {
417 if ((*ic_data_array)[i] != NULL) { 420 if ((*ic_data_array)[i] != NULL) {
418 ISL_Print("%" Pd " ", i); 421 ISL_Print("%" Pd " ", i);
419 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); 422 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
420 } 423 }
421 } 424 }
422 } 425 }
423 } 426 }
424 427
425 flow_graph = pipeline->BuildFlowGraph(parsed_function, 428 flow_graph = pipeline->BuildFlowGraph(parsed_function,
426 *ic_data_array, 429 *ic_data_array,
427 osr_id); 430 osr_id,
431 zone);
428 } 432 }
429 433
430 const bool print_flow_graph = 434 const bool print_flow_graph =
431 (FLAG_print_flow_graph || 435 (FLAG_print_flow_graph ||
432 (optimized && FLAG_print_flow_graph_optimized)) && 436 (optimized && FLAG_print_flow_graph_optimized)) &&
433 FlowGraphPrinter::ShouldPrint(function); 437 FlowGraphPrinter::ShouldPrint(function);
434 438
435 if (print_flow_graph) { 439 if (print_flow_graph) {
436 if (osr_id == Isolate::kNoDeoptId) { 440 if (osr_id == Isolate::kNoDeoptId) {
437 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 441 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 // We got an error during compilation. 1037 // We got an error during compilation.
1034 error = isolate->object_store()->sticky_error(); 1038 error = isolate->object_store()->sticky_error();
1035 isolate->object_store()->clear_sticky_error(); 1039 isolate->object_store()->clear_sticky_error();
1036 return error.raw(); 1040 return error.raw();
1037 } 1041 }
1038 UNREACHABLE(); 1042 UNREACHABLE();
1039 return Error::null(); 1043 return Error::null();
1040 } 1044 }
1041 1045
1042 1046
1043 RawError* Compiler::CompileFunction(Isolate* isolate, 1047 RawError* Compiler::CompileFunction(Thread* thread,
1044 const Function& function) { 1048 const Function& function) {
1045 VMTagScope tagScope(isolate, VMTag::kCompileUnoptimizedTagId); 1049 VMTagScope tagScope(thread->isolate(), VMTag::kCompileUnoptimizedTagId);
1046 CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function); 1050 CompilationPipeline* pipeline =
1051 CompilationPipeline::New(thread->zone(), function);
1047 return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId); 1052 return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId);
1048 } 1053 }
1049 1054
1050 1055
1051 RawError* Compiler::CompileOptimizedFunction(Isolate* isolate, 1056 RawError* Compiler::CompileOptimizedFunction(Thread* thread,
1052 const Function& function, 1057 const Function& function,
1053 intptr_t osr_id) { 1058 intptr_t osr_id) {
1054 VMTagScope tagScope(isolate, VMTag::kCompileOptimizedTagId); 1059 VMTagScope tagScope(thread->isolate(), VMTag::kCompileOptimizedTagId);
1055 CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function); 1060 CompilationPipeline* pipeline =
1061 CompilationPipeline::New(thread->zone(), function);
1056 return CompileFunctionHelper(pipeline, function, true, osr_id); 1062 return CompileFunctionHelper(pipeline, function, true, osr_id);
1057 } 1063 }
1058 1064
1059 1065
1060 // This is only used from unit tests. 1066 // This is only used from unit tests.
1061 RawError* Compiler::CompileParsedFunction( 1067 RawError* Compiler::CompileParsedFunction(
1062 ParsedFunction* parsed_function) { 1068 ParsedFunction* parsed_function) {
1063 Isolate* isolate = Isolate::Current(); 1069 Isolate* isolate = Isolate::Current();
1064 LongJumpScope jump; 1070 LongJumpScope jump;
1065 if (setjmp(*jump.Set()) == 0) { 1071 if (setjmp(*jump.Set()) == 0) {
(...skipping 13 matching lines...) Expand all
1079 error = isolate->object_store()->sticky_error(); 1085 error = isolate->object_store()->sticky_error();
1080 isolate->object_store()->clear_sticky_error(); 1086 isolate->object_store()->clear_sticky_error();
1081 return error.raw(); 1087 return error.raw();
1082 } 1088 }
1083 UNREACHABLE(); 1089 UNREACHABLE();
1084 return Error::null(); 1090 return Error::null();
1085 } 1091 }
1086 1092
1087 1093
1088 RawError* Compiler::CompileAllFunctions(const Class& cls) { 1094 RawError* Compiler::CompileAllFunctions(const Class& cls) {
1089 Isolate* isolate = Isolate::Current(); 1095 Thread* thread = Thread::Current();
1090 Error& error = Error::Handle(isolate); 1096 Zone* zone = thread->zone();
1091 Array& functions = Array::Handle(isolate, cls.functions()); 1097 Error& error = Error::Handle(zone);
1092 Function& func = Function::Handle(isolate); 1098 Array& functions = Array::Handle(zone, cls.functions());
1099 Function& func = Function::Handle(zone);
1093 // Class dynamic lives in the vm isolate. Its array fields cannot be set to 1100 // Class dynamic lives in the vm isolate. Its array fields cannot be set to
1094 // an empty array. 1101 // an empty array.
1095 if (functions.IsNull()) { 1102 if (functions.IsNull()) {
1096 ASSERT(cls.IsDynamicClass()); 1103 ASSERT(cls.IsDynamicClass());
1097 return error.raw(); 1104 return error.raw();
1098 } 1105 }
1099 // Compile all the regular functions. 1106 // Compile all the regular functions.
1100 for (int i = 0; i < functions.Length(); i++) { 1107 for (int i = 0; i < functions.Length(); i++) {
1101 func ^= functions.At(i); 1108 func ^= functions.At(i);
1102 ASSERT(!func.IsNull()); 1109 ASSERT(!func.IsNull());
1103 if (!func.HasCode() && 1110 if (!func.HasCode() &&
1104 !func.is_abstract() && 1111 !func.is_abstract() &&
1105 !func.IsRedirectingFactory()) { 1112 !func.IsRedirectingFactory()) {
1106 error = CompileFunction(isolate, func); 1113 error = CompileFunction(thread, func);
1107 if (!error.IsNull()) { 1114 if (!error.IsNull()) {
1108 return error.raw(); 1115 return error.raw();
1109 } 1116 }
1110 func.ClearCode(); 1117 func.ClearCode();
1111 } 1118 }
1112 } 1119 }
1113 // Inner functions get added to the closures array. As part of compilation 1120 // Inner functions get added to the closures array. As part of compilation
1114 // more closures can be added to the end of the array. Compile all the 1121 // more closures can be added to the end of the array. Compile all the
1115 // closures until we have reached the end of the "worklist". 1122 // closures until we have reached the end of the "worklist".
1116 GrowableObjectArray& closures = 1123 GrowableObjectArray& closures =
1117 GrowableObjectArray::Handle(isolate, cls.closures()); 1124 GrowableObjectArray::Handle(zone, cls.closures());
1118 if (!closures.IsNull()) { 1125 if (!closures.IsNull()) {
1119 for (int i = 0; i < closures.Length(); i++) { 1126 for (int i = 0; i < closures.Length(); i++) {
1120 func ^= closures.At(i); 1127 func ^= closures.At(i);
1121 if (!func.HasCode()) { 1128 if (!func.HasCode()) {
1122 error = CompileFunction(isolate, func); 1129 error = CompileFunction(thread, func);
1123 if (!error.IsNull()) { 1130 if (!error.IsNull()) {
1124 return error.raw(); 1131 return error.raw();
1125 } 1132 }
1126 func.ClearCode(); 1133 func.ClearCode();
1127 } 1134 }
1128 } 1135 }
1129 } 1136 }
1130 return error.raw(); 1137 return error.raw();
1131 } 1138 }
1132 1139
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 const Object& result = 1232 const Object& result =
1226 PassiveObject::Handle(isolate->object_store()->sticky_error()); 1233 PassiveObject::Handle(isolate->object_store()->sticky_error());
1227 isolate->object_store()->clear_sticky_error(); 1234 isolate->object_store()->clear_sticky_error();
1228 return result.raw(); 1235 return result.raw();
1229 } 1236 }
1230 UNREACHABLE(); 1237 UNREACHABLE();
1231 return Object::null(); 1238 return Object::null();
1232 } 1239 }
1233 1240
1234 } // namespace dart 1241 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698