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

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

Issue 10389023: Fixed compilation time measurement, restructure some code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('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) 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 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // Use previously compiled code. 124 // Use previously compiled code.
125 function.SetCode(Code::Handle(function.unoptimized_code())); 125 function.SetCode(Code::Handle(function.unoptimized_code()));
126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); 126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
127 if (FLAG_trace_compiler) { 127 if (FLAG_trace_compiler) {
128 OS::Print("--> restoring entry at 0x%x\n", 128 OS::Print("--> restoring entry at 0x%x\n",
129 Code::Handle(function.unoptimized_code()).EntryPoint()); 129 Code::Handle(function.unoptimized_code()).EntryPoint());
130 } 130 }
131 } 131 }
132 132
133 133
134 static void CompileParsedFunctionHelper( 134 // Return false if bailed out.
135 static bool CompileWithNewCompiler(
135 const ParsedFunction& parsed_function, bool optimized) { 136 const ParsedFunction& parsed_function, bool optimized) {
137 bool is_compiled = false;
136 Isolate* isolate = Isolate::Current(); 138 Isolate* isolate = Isolate::Current();
137 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 139 LongJump* old_base = isolate->long_jump_base();
138 const Function& function = parsed_function.function(); 140 LongJump bailout_jump;
139 const char* function_fullname = function.ToFullyQualifiedCString(); 141 isolate->set_long_jump_base(&bailout_jump);
140 bool is_compiled = false; 142 if (setjmp(*bailout_jump.Set()) == 0) {
141 // TODO(srdjan): Remove once the old compiler has been ripped out. 143 GrowableArray<BlockEntryInstr*> block_order;
142 #if defined(TARGET_ARCH_X64) 144 // TimerScope needs an isolate to be properly terminated in case of a
143 const bool use_new_compiler = true; 145 // LongJump.
144 #else 146 {
145 const bool use_new_compiler = FLAG_use_new_compiler; 147 TimerScope timer(FLAG_compiler_stats,
146 #endif 148 &CompilerStats::graphbuilder_timer,
147 if (use_new_compiler) { 149 isolate);
148 LongJump* old_base = isolate->long_jump_base(); 150 CompilerStats::graphbuilder_timer.Start();
149 LongJump bailout_jump;
150 isolate->set_long_jump_base(&bailout_jump);
151 if (setjmp(*bailout_jump.Set()) == 0) {
152 FlowGraphBuilder graph_builder(parsed_function); 151 FlowGraphBuilder graph_builder(parsed_function);
153 graph_builder.BuildGraph(optimized); 152 graph_builder.BuildGraph(optimized);
154 153
155 // The non-optimizing compiler compiles blocks in reverse postorder, 154 // The non-optimizing compiler compiles blocks in reverse postorder,
156 // because it is a 'natural' order for the human reader of the 155 // because it is a 'natural' order for the human reader of the
157 // generated code. 156 // generated code.
158 intptr_t length = graph_builder.postorder_block_entries().length(); 157 intptr_t length = graph_builder.postorder_block_entries().length();
159 GrowableArray<BlockEntryInstr*> block_order(length);
160 for (intptr_t i = length - 1; i >= 0; --i) { 158 for (intptr_t i = length - 1; i >= 0; --i) {
161 block_order.Add(graph_builder.postorder_block_entries()[i]); 159 block_order.Add(graph_builder.postorder_block_entries()[i]);
162 } 160 }
163 161
164 if (optimized) { 162 if (optimized) {
165 // Transition to optimized code only from unoptimized code ... 163 // Transition to optimized code only from unoptimized code ...
166 // for now. 164 // for now.
167 ASSERT(function.HasCode()); 165 ASSERT(parsed_function.function().HasCode());
168 ASSERT(!function.HasOptimizedCode()); 166 ASSERT(!parsed_function.function().HasOptimizedCode());
169 // Do not use type feedback to optimize a function that was 167 // Do not use type feedback to optimize a function that was
170 // deoptimized too often. 168 // deoptimized too often.
171 if (parsed_function.function().deoptimization_counter() < 169 if (parsed_function.function().deoptimization_counter() <
172 FLAG_deoptimization_counter_threshold) { 170 FLAG_deoptimization_counter_threshold) {
173 // Extract type feedback etc. 171 // Extract type feedback etc.
174 } 172 }
175 } 173 }
176 Assembler assembler; 174 }
177 FlowGraphCompiler graph_compiler(&assembler, parsed_function, 175
178 block_order, optimized); 176 Assembler assembler;
177 FlowGraphCompiler graph_compiler(&assembler, parsed_function,
178 block_order, optimized);
179 {
180 TimerScope timer(FLAG_compiler_stats,
181 &CompilerStats::graphcompiler_timer,
182 isolate);
179 graph_compiler.CompileGraph(); 183 graph_compiler.CompileGraph();
180 184 }
185 {
181 TimerScope timer(FLAG_compiler_stats, 186 TimerScope timer(FLAG_compiler_stats,
182 &CompilerStats::codefinalizer_timer); 187 &CompilerStats::codefinalizer_timer,
188 isolate);
189 const Function& function = parsed_function.function();
183 const Code& code = 190 const Code& code =
184 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); 191 Code::Handle(Code::FinalizeCodeForFunction(function, &assembler));
siva 2012/05/08 22:08:45 Why not have FinalizeCode and FinalizeStubCode one
185 code.set_is_optimized(optimized); 192 code.set_is_optimized(optimized);
186 graph_compiler.FinalizePcDescriptors(code); 193 graph_compiler.FinalizePcDescriptors(code);
187 graph_compiler.FinalizeStackmaps(code); 194 graph_compiler.FinalizeStackmaps(code);
188 graph_compiler.FinalizeVarDescriptors(code); 195 graph_compiler.FinalizeVarDescriptors(code);
189 graph_compiler.FinalizeExceptionHandlers(code); 196 graph_compiler.FinalizeExceptionHandlers(code);
190 if (optimized) { 197 if (optimized) {
191 function.SetCode(code); 198 function.SetCode(code);
192 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); 199 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
193 if (FLAG_trace_compiler) { 200 if (FLAG_trace_compiler) {
194 OS::Print("--> patching entry 0x%x\n", 201 OS::Print("--> patching entry 0x%x\n",
195 Code::Handle(function.unoptimized_code()).EntryPoint()); 202 Code::Handle(function.unoptimized_code()).EntryPoint());
196 } 203 }
197 } else { 204 } else {
198 function.set_unoptimized_code(code); 205 function.set_unoptimized_code(code);
199 function.SetCode(code); 206 function.SetCode(code);
200 ASSERT(CodePatcher::CodeIsPatchable(code)); 207 ASSERT(CodePatcher::CodeIsPatchable(code));
201 } 208 }
202 is_compiled = true; 209 is_compiled = true;
203 } else {
204 // We bailed out.
205 Error& bailout_error = Error::Handle(
206 isolate->object_store()->sticky_error());
207 isolate->object_store()->clear_sticky_error();
208 if (FLAG_trace_bailout) {
209 OS::Print("%s\n", bailout_error.ToErrorCString());
210 }
211 } 210 }
212 isolate->set_long_jump_base(old_base); 211 } else {
212 // We bailed out.
213 Error& bailout_error = Error::Handle(
214 isolate->object_store()->sticky_error());
215 isolate->object_store()->clear_sticky_error();
216 if (FLAG_trace_bailout) {
217 OS::Print("%s\n", bailout_error.ToErrorCString());
218 }
siva 2012/05/08 22:08:45 You may get a compilation error on the build bot b
srdjan 2012/05/08 23:54:32 Done.
213 } 219 }
220 isolate->set_long_jump_base(old_base);
221 return is_compiled;
222 }
214 223
215 if (!is_compiled) { 224
216 Assembler assembler; 225 static void CompileWithOldCompiler(
217 if (optimized) { 226 const ParsedFunction& parsed_function, bool optimized) {
218 // Transition to optimized code only from unoptimized code ... 227 const Function& function = parsed_function.function();
219 // for now. 228 Assembler assembler;
220 ASSERT(function.HasCode()); 229 if (optimized) {
221 ASSERT(!function.HasOptimizedCode()); 230 // Transition to optimized code only from unoptimized code ...
222 // Do not use type feedback to optimize a function that was 231 // for now.
223 // deoptimized too often. 232 ASSERT(function.HasCode());
224 if (parsed_function.function().deoptimization_counter() < 233 ASSERT(!function.HasOptimizedCode());
225 FLAG_deoptimization_counter_threshold) { 234 // Do not use type feedback to optimize a function that was
226 ExtractTypeFeedback( 235 // deoptimized too often.
227 Code::Handle(parsed_function.function().unoptimized_code()), 236 if (parsed_function.function().deoptimization_counter() <
228 parsed_function.node_sequence()); 237 FLAG_deoptimization_counter_threshold) {
229 } 238 TimerScope timer(FLAG_compiler_stats,
230 OptimizingCodeGenerator code_gen(&assembler, parsed_function); 239 &CompilerStats::graphbuilder_timer);
240 ExtractTypeFeedback(
241 Code::Handle(parsed_function.function().unoptimized_code()),
242 parsed_function.node_sequence());
243 }
244 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
245 {
246 TimerScope timer(FLAG_compiler_stats,
247 &CompilerStats::graphcompiler_timer);
231 code_gen.GenerateCode(); 248 code_gen.GenerateCode();
249 }
250 {
232 TimerScope timer(FLAG_compiler_stats, 251 TimerScope timer(FLAG_compiler_stats,
233 &CompilerStats::codefinalizer_timer); 252 &CompilerStats::codefinalizer_timer);
234 Code& code = Code::Handle( 253 Code& code = Code::Handle(
235 Code::FinalizeCode(function_fullname, &assembler)); 254 Code::FinalizeCodeForFunction(function, &assembler));
236 code.set_is_optimized(true); 255 code.set_is_optimized(true);
237 code_gen.FinalizePcDescriptors(code); 256 code_gen.FinalizePcDescriptors(code);
238 code_gen.FinalizeStackmaps(code); 257 code_gen.FinalizeStackmaps(code);
239 code_gen.FinalizeExceptionHandlers(code); 258 code_gen.FinalizeExceptionHandlers(code);
240 function.SetCode(code); 259 function.SetCode(code);
241 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); 260 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
242 if (FLAG_trace_compiler) { 261 }
243 OS::Print("--> patching entry 0x%x\n", 262 if (FLAG_trace_compiler) {
244 Code::Handle(function.unoptimized_code()).EntryPoint()); 263 OS::Print("--> patching entry 0x%x\n",
245 } 264 Code::Handle(function.unoptimized_code()).EntryPoint());
246 } else { 265 }
247 // Compile unoptimized code. 266 } else {
248 ASSERT(!function.HasCode()); 267 // Compile unoptimized code.
249 // Compiling first time. 268 ASSERT(!function.HasCode());
250 CodeGenerator code_gen(&assembler, parsed_function); 269 // Compiling first time.
270 CodeGenerator code_gen(&assembler, parsed_function);
271 {
272 TimerScope timer(FLAG_compiler_stats,
273 &CompilerStats::graphcompiler_timer);
251 code_gen.GenerateCode(); 274 code_gen.GenerateCode();
275 }
276 {
252 TimerScope timer(FLAG_compiler_stats, 277 TimerScope timer(FLAG_compiler_stats,
253 &CompilerStats::codefinalizer_timer); 278 &CompilerStats::codefinalizer_timer);
254 const Code& code = 279 const Code& code =
255 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); 280 Code::Handle(Code::FinalizeCodeForFunction(function, &assembler));
256 code.set_is_optimized(false); 281 code.set_is_optimized(false);
257 code_gen.FinalizePcDescriptors(code); 282 code_gen.FinalizePcDescriptors(code);
258 code_gen.FinalizeStackmaps(code); 283 code_gen.FinalizeStackmaps(code);
259 code_gen.FinalizeVarDescriptors(code); 284 code_gen.FinalizeVarDescriptors(code);
260 code_gen.FinalizeExceptionHandlers(code); 285 code_gen.FinalizeExceptionHandlers(code);
261 function.set_unoptimized_code(code); 286 function.set_unoptimized_code(code);
262 function.SetCode(code); 287 function.SetCode(code);
263 ASSERT(CodePatcher::CodeIsPatchable(code)); 288 ASSERT(CodePatcher::CodeIsPatchable(code));
264 } 289 }
265 } 290 }
266 } 291 }
267 292
293 static void CompileParsedFunctionHelper(
294 const ParsedFunction& parsed_function, bool optimized) {
295 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
296 bool is_compiled = false;
297 // TODO(srdjan): Remove once the old compiler has been ripped out.
298 #if defined(TARGET_ARCH_X64)
299 const bool use_new_compiler = true;
300 #else
301 const bool use_new_compiler = FLAG_use_new_compiler;
302 #endif
303 if (use_new_compiler) {
304 is_compiled = CompileWithNewCompiler(parsed_function, optimized);
305 }
306
307 if (!is_compiled) {
308 CompileWithOldCompiler(parsed_function, optimized);
309 }
310 }
311
268 312
269 static RawError* CompileFunctionHelper(const Function& function, 313 static RawError* CompileFunctionHelper(const Function& function,
270 bool optimized) { 314 bool optimized) {
271 Isolate* isolate = Isolate::Current(); 315 Isolate* isolate = Isolate::Current();
272 LongJump* base = isolate->long_jump_base(); 316 LongJump* base = isolate->long_jump_base();
273 LongJump jump; 317 LongJump jump;
274 isolate->set_long_jump_base(&jump); 318 isolate->set_long_jump_base(&jump);
275 // Skips parsing if we need to only install unoptimized code. 319 // Skips parsing if we need to only install unoptimized code.
276 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { 320 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) {
277 InstallUnoptimizedCode(function); 321 InstallUnoptimizedCode(function);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 isolate->object_store()->clear_sticky_error(); 510 isolate->object_store()->clear_sticky_error();
467 isolate->set_long_jump_base(base); 511 isolate->set_long_jump_base(base);
468 return result.raw(); 512 return result.raw();
469 } 513 }
470 UNREACHABLE(); 514 UNREACHABLE();
471 return Object::null(); 515 return Object::null();
472 } 516 }
473 517
474 518
475 } // namespace dart 519 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698