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

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

Issue 10665038: Remove old code generator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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_patcher_x64_test.cc ('k') | runtime/vm/dart_entry.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) 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"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/debugger.h" 12 #include "vm/debugger.h"
13 #include "vm/disassembler.h" 13 #include "vm/disassembler.h"
14 #include "vm/exceptions.h" 14 #include "vm/exceptions.h"
15 #include "vm/flags.h" 15 #include "vm/flags.h"
16 #include "vm/flow_graph_allocator.h" 16 #include "vm/flow_graph_allocator.h"
17 #include "vm/flow_graph_builder.h" 17 #include "vm/flow_graph_builder.h"
18 #include "vm/flow_graph_compiler.h" 18 #include "vm/flow_graph_compiler.h"
19 #include "vm/flow_graph_optimizer.h" 19 #include "vm/flow_graph_optimizer.h"
20 #include "vm/longjump.h" 20 #include "vm/longjump.h"
21 #include "vm/object.h" 21 #include "vm/object.h"
22 #include "vm/object_store.h" 22 #include "vm/object_store.h"
23 #include "vm/opt_code_generator.h"
24 #include "vm/os.h" 23 #include "vm/os.h"
25 #include "vm/parser.h" 24 #include "vm/parser.h"
26 #include "vm/scanner.h" 25 #include "vm/scanner.h"
27 #include "vm/timer.h" 26 #include "vm/timer.h"
28 27
29 namespace dart { 28 namespace dart {
30 29
31 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code."); 30 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code.");
32 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); 31 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
33 DEFINE_FLAG(int, deoptimization_counter_threshold, 5, 32 DEFINE_FLAG(int, deoptimization_counter_threshold, 5,
(...skipping 10 matching lines...) Expand all
44 ASSERT(arguments.Count() == kCompileFunctionRuntimeEntry.argument_count()); 43 ASSERT(arguments.Count() == kCompileFunctionRuntimeEntry.argument_count());
45 const Function& function = Function::CheckedHandle(arguments.At(0)); 44 const Function& function = Function::CheckedHandle(arguments.At(0));
46 ASSERT(!function.HasCode()); 45 ASSERT(!function.HasCode());
47 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 46 const Error& error = Error::Handle(Compiler::CompileFunction(function));
48 if (!error.IsNull()) { 47 if (!error.IsNull()) {
49 Exceptions::PropagateError(error); 48 Exceptions::PropagateError(error);
50 } 49 }
51 } 50 }
52 51
53 52
54 // Extracts IC data associated with a node id.
55 // TODO(srdjan): Check performance impact of node id search loop.
56 static void ExtractTypeFeedback(const Code& code,
57 SequenceNode* sequence_node) {
58 ASSERT(!code.IsNull() && !code.is_optimized());
59 GrowableArray<AstNode*> all_nodes;
60 sequence_node->CollectAllNodes(&all_nodes);
61 GrowableArray<intptr_t> node_ids;
62 const GrowableObjectArray& ic_data_objs =
63 GrowableObjectArray::Handle(GrowableObjectArray::New());
64 code.ExtractIcDataArraysAtCalls(&node_ids, ic_data_objs);
65 ICData& ic_data_obj = ICData::Handle();
66 for (intptr_t i = 0; i < node_ids.length(); i++) {
67 intptr_t node_id = node_ids[i];
68 bool found_node = false;
69 for (intptr_t n = 0; n < all_nodes.length(); n++) {
70 if (all_nodes[n]->id() == node_id) {
71 found_node = true;
72 // Make sure we assign ic data array only once.
73 ASSERT(all_nodes[n]->ic_data().IsNull());
74 ic_data_obj ^= ic_data_objs.At(i);
75 all_nodes[n]->set_ic_data(ic_data_obj);
76 }
77 }
78 ASSERT(found_node);
79 }
80 }
81
82
83 // Returns an array indexed by computation id, containing the extracted ICData. 53 // Returns an array indexed by computation id, containing the extracted ICData.
84 static RawArray* ExtractTypeFeedbackArray(const Code& code) { 54 static RawArray* ExtractTypeFeedbackArray(const Code& code) {
85 ASSERT(!code.IsNull() && !code.is_optimized()); 55 ASSERT(!code.IsNull() && !code.is_optimized());
86 GrowableArray<intptr_t> computation_ids; 56 GrowableArray<intptr_t> computation_ids;
87 const GrowableObjectArray& ic_data_objs = 57 const GrowableObjectArray& ic_data_objs =
88 GrowableObjectArray::Handle(GrowableObjectArray::New()); 58 GrowableObjectArray::Handle(GrowableObjectArray::New());
89 const intptr_t max_id = 59 const intptr_t max_id =
90 code.ExtractIcDataArraysAtCalls(&computation_ids, ic_data_objs); 60 code.ExtractIcDataArraysAtCalls(&computation_ids, ic_data_objs);
91 const Array& result = Array::Handle(Array::New(max_id + 1)); 61 const Array& result = Array::Handle(Array::New(max_id + 1));
92 for (intptr_t i = 0; i < computation_ids.length(); i++) { 62 for (intptr_t i = 0; i < computation_ids.length(); i++) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // Use previously compiled code. 109 // Use previously compiled code.
140 function.SetCode(Code::Handle(function.unoptimized_code())); 110 function.SetCode(Code::Handle(function.unoptimized_code()));
141 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); 111 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
142 if (FLAG_trace_compiler) { 112 if (FLAG_trace_compiler) {
143 OS::Print("--> restoring entry at 0x%x\n", 113 OS::Print("--> restoring entry at 0x%x\n",
144 Code::Handle(function.unoptimized_code()).EntryPoint()); 114 Code::Handle(function.unoptimized_code()).EntryPoint());
145 } 115 }
146 } 116 }
147 117
148 118
149 // Return false if bailed out. 119 static void CompileParsedFunctionHelper(
150 static bool CompileWithNewCompiler(
151 const ParsedFunction& parsed_function, bool optimized) { 120 const ParsedFunction& parsed_function, bool optimized) {
152 bool is_compiled = false; 121 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
153 Isolate* isolate = Isolate::Current(); 122 Isolate* isolate = Isolate::Current();
154 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null. 123 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null.
155 const intptr_t prev_cid = isolate->computation_id(); 124 const intptr_t prev_cid = isolate->computation_id();
156 isolate->set_computation_id(0); 125 isolate->set_computation_id(0);
157 LongJump* old_base = isolate->long_jump_base(); 126 LongJump* old_base = isolate->long_jump_base();
158 LongJump bailout_jump; 127 LongJump bailout_jump;
159 isolate->set_long_jump_base(&bailout_jump); 128 isolate->set_long_jump_base(&bailout_jump);
160 if (setjmp(*bailout_jump.Set()) == 0) { 129 if (setjmp(*bailout_jump.Set()) == 0) {
161 GrowableArray<BlockEntryInstr*> block_order; 130 GrowableArray<BlockEntryInstr*> block_order;
162 // TimerScope needs an isolate to be properly terminated in case of a 131 // TimerScope needs an isolate to be properly terminated in case of a
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 if (FLAG_trace_compiler) { 206 if (FLAG_trace_compiler) {
238 OS::Print("--> patching entry 0x%x\n", 207 OS::Print("--> patching entry 0x%x\n",
239 Code::Handle(function.unoptimized_code()).EntryPoint()); 208 Code::Handle(function.unoptimized_code()).EntryPoint());
240 } 209 }
241 } else { 210 } else {
242 function.set_unoptimized_code(code); 211 function.set_unoptimized_code(code);
243 function.SetCode(code); 212 function.SetCode(code);
244 ASSERT(CodePatcher::CodeIsPatchable(code)); 213 ASSERT(CodePatcher::CodeIsPatchable(code));
245 } 214 }
246 } 215 }
247 is_compiled = true;
248 } else { 216 } else {
249 // We bailed out. 217 UNREACHABLE();
srdjan 2012/06/26 16:06:51 We can bailout of optimized code (e.g., during ssa
250 Error& bailout_error = Error::Handle(
251 isolate->object_store()->sticky_error());
252 isolate->object_store()->clear_sticky_error();
253 if (FLAG_trace_bailout) {
254 OS::Print("%s\n", bailout_error.ToErrorCString());
255 }
256 is_compiled = false;
257 } 218 }
258 // Reset global isolate state. 219 // Reset global isolate state.
259 isolate->set_ic_data_array(Array::null()); 220 isolate->set_ic_data_array(Array::null());
260 isolate->set_long_jump_base(old_base); 221 isolate->set_long_jump_base(old_base);
261 isolate->set_computation_id(prev_cid); 222 isolate->set_computation_id(prev_cid);
262 return is_compiled;
263 }
264
265
266 static void CompileWithOldCompiler(
267 const ParsedFunction& parsed_function, bool optimized) {
268 const Function& function = parsed_function.function();
269 Assembler assembler;
270 if (optimized) {
271 // Transition to optimized code only from unoptimized code ...
272 // for now.
273 ASSERT(function.HasCode());
274 ASSERT(!function.HasOptimizedCode());
275 // Do not use type feedback to optimize a function that was
276 // deoptimized too often.
277 if (parsed_function.function().deoptimization_counter() <
278 FLAG_deoptimization_counter_threshold) {
279 TimerScope timer(FLAG_compiler_stats,
280 &CompilerStats::graphbuilder_timer);
281 ExtractTypeFeedback(
282 Code::Handle(parsed_function.function().unoptimized_code()),
283 parsed_function.node_sequence());
284 }
285 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
286 {
287 TimerScope timer(FLAG_compiler_stats,
288 &CompilerStats::graphcompiler_timer);
289 code_gen.GenerateCode();
290 }
291 {
292 TimerScope timer(FLAG_compiler_stats,
293 &CompilerStats::codefinalizer_timer);
294 Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
295 code.set_is_optimized(true);
296 code_gen.FinalizePcDescriptors(code);
297 code_gen.FinalizeStackmaps(code);
298 code_gen.FinalizeExceptionHandlers(code);
299 code_gen.FinalizeComments(code);
300 function.SetCode(code);
301 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
302 }
303 if (FLAG_trace_compiler) {
304 OS::Print("--> patching entry 0x%x\n",
305 Code::Handle(function.unoptimized_code()).EntryPoint());
306 }
307 } else {
308 // Compile unoptimized code.
309 ASSERT(!function.HasCode());
310 // Compiling first time.
311 CodeGenerator code_gen(&assembler, parsed_function);
312 {
313 TimerScope timer(FLAG_compiler_stats,
314 &CompilerStats::graphcompiler_timer);
315 code_gen.GenerateCode();
316 }
317 {
318 TimerScope timer(FLAG_compiler_stats,
319 &CompilerStats::codefinalizer_timer);
320 const Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
321 code.set_is_optimized(false);
322 code_gen.FinalizePcDescriptors(code);
323 code_gen.FinalizeStackmaps(code);
324 code_gen.FinalizeVarDescriptors(code);
325 code_gen.FinalizeExceptionHandlers(code);
326 code_gen.FinalizeComments(code);
327 function.set_unoptimized_code(code);
328 function.SetCode(code);
329 ASSERT(CodePatcher::CodeIsPatchable(code));
330 }
331 }
332 }
333
334 static void CompileParsedFunctionHelper(
335 const ParsedFunction& parsed_function, bool optimized) {
336 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
337 bool is_compiled = false;
338 // TODO(srdjan): Remove once the old compiler has been ripped out.
339 #if defined(TARGET_ARCH_X64)
340 const bool use_new_compiler = true;
341 #else
342 const bool use_new_compiler = FLAG_use_new_compiler;
343 #endif
344 if (use_new_compiler) {
345 is_compiled = CompileWithNewCompiler(parsed_function, optimized);
346 if (!is_compiled && optimized) {
347 // When bailing out from the optimizing compiler, mark function as
348 // non-optimizable and return.
349 parsed_function.function().set_is_optimizable(false);
350 return;
351 }
352 }
353
354 if (!is_compiled) {
355 CompileWithOldCompiler(parsed_function, optimized);
356 }
357 } 223 }
358 224
359 225
360 static RawError* CompileFunctionHelper(const Function& function, 226 static RawError* CompileFunctionHelper(const Function& function,
361 bool optimized) { 227 bool optimized) {
362 Isolate* isolate = Isolate::Current(); 228 Isolate* isolate = Isolate::Current();
363 LongJump* base = isolate->long_jump_base(); 229 LongJump* base = isolate->long_jump_base();
364 LongJump jump; 230 LongJump jump;
365 isolate->set_long_jump_base(&jump); 231 isolate->set_long_jump_base(&jump);
366 // Skips parsing if we need to only install unoptimized code. 232 // Skips parsing if we need to only install unoptimized code.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 isolate->object_store()->clear_sticky_error(); 448 isolate->object_store()->clear_sticky_error();
583 isolate->set_long_jump_base(base); 449 isolate->set_long_jump_base(base);
584 return result.raw(); 450 return result.raw();
585 } 451 }
586 UNREACHABLE(); 452 UNREACHABLE();
587 return Object::null(); 453 return Object::null();
588 } 454 }
589 455
590 456
591 } // namespace dart 457 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_x64_test.cc ('k') | runtime/vm/dart_entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698