OLD | NEW |
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_index_table.h" | 10 #include "vm/code_index_table.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 isolate->set_long_jump_base(old_base); | 155 isolate->set_long_jump_base(old_base); |
156 // Currently, always fails and falls through to the old compiler. | 156 // Currently, always fails and falls through to the old compiler. |
157 } | 157 } |
158 CodeIndexTable* code_index_table = isolate->code_index_table(); | 158 CodeIndexTable* code_index_table = isolate->code_index_table(); |
159 ASSERT(code_index_table != NULL); | 159 ASSERT(code_index_table != NULL); |
160 Assembler assembler; | 160 Assembler assembler; |
161 if (optimized) { | 161 if (optimized) { |
162 // Transition to optimized code only from unoptimized code ... for now. | 162 // Transition to optimized code only from unoptimized code ... for now. |
163 ASSERT(function.HasCode()); | 163 ASSERT(function.HasCode()); |
164 ASSERT(!Code::Handle(function.code()).is_optimized()); | 164 ASSERT(!function.HasOptimizedCode()); |
165 // Do not use type feedback to optimize a function that was deoptimized. | 165 // Do not use type feedback to optimize a function that was deoptimized |
| 166 // too often. |
166 if (parsed_function.function().deoptimization_counter() < | 167 if (parsed_function.function().deoptimization_counter() < |
167 FLAG_deoptimization_counter_threshold) { | 168 FLAG_deoptimization_counter_threshold) { |
168 ExtractTypeFeedback(Code::Handle(parsed_function.function().code()), | 169 ExtractTypeFeedback( |
169 parsed_function.node_sequence()); | 170 Code::Handle(parsed_function.function().unoptimized_code()), |
| 171 parsed_function.node_sequence()); |
170 } | 172 } |
171 OptimizingCodeGenerator code_gen(&assembler, parsed_function); | 173 OptimizingCodeGenerator code_gen(&assembler, parsed_function); |
172 code_gen.GenerateCode(); | 174 code_gen.GenerateCode(); |
173 Code& code = Code::Handle( | 175 Code& code = Code::Handle( |
174 Code::FinalizeCode(function_fullname, &assembler)); | 176 Code::FinalizeCode(function_fullname, &assembler)); |
175 code.set_is_optimized(true); | 177 code.set_is_optimized(true); |
176 code_gen.FinalizePcDescriptors(code); | 178 code_gen.FinalizePcDescriptors(code); |
177 code_gen.FinalizeExceptionHandlers(code); | 179 code_gen.FinalizeExceptionHandlers(code); |
178 function.SetCode(code); | 180 function.SetCode(code); |
179 code_index_table->AddFunction(function); | 181 code_index_table->AddCode(code); |
180 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); | 182 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); |
181 if (FLAG_trace_compiler) { | 183 if (FLAG_trace_compiler) { |
182 OS::Print("--> patching entry 0x%x\n", | 184 OS::Print("--> patching entry 0x%x\n", |
183 Code::Handle(function.unoptimized_code()).EntryPoint()); | 185 Code::Handle(function.unoptimized_code()).EntryPoint()); |
184 } | 186 } |
185 } else { | 187 } else { |
186 // Unoptimized code. | 188 // Unoptimized code. |
187 if (Code::Handle(function.unoptimized_code()).IsNull()) { | 189 if (Code::Handle(function.unoptimized_code()).IsNull()) { |
188 ASSERT(Code::Handle(function.code()).IsNull()); | 190 ASSERT(!function.HasCode()); |
189 // Compiling first time. | 191 // Compiling first time. |
190 CodeGenerator code_gen(&assembler, parsed_function); | 192 CodeGenerator code_gen(&assembler, parsed_function); |
191 code_gen.GenerateCode(); | 193 code_gen.GenerateCode(); |
192 const Code& code = | 194 const Code& code = |
193 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); | 195 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); |
194 code.set_is_optimized(false); | 196 code.set_is_optimized(false); |
195 code_gen.FinalizePcDescriptors(code); | 197 code_gen.FinalizePcDescriptors(code); |
196 code_gen.FinalizeVarDescriptors(code); | 198 code_gen.FinalizeVarDescriptors(code); |
197 code_gen.FinalizeExceptionHandlers(code); | 199 code_gen.FinalizeExceptionHandlers(code); |
198 function.set_unoptimized_code(code); | 200 function.set_unoptimized_code(code); |
199 function.SetCode(code); | 201 function.SetCode(code); |
200 ASSERT(CodePatcher::CodeIsPatchable(code)); | 202 ASSERT(CodePatcher::CodeIsPatchable(code)); |
201 code_index_table->AddFunction(function); | 203 code_index_table->AddCode(code); |
202 } else { | 204 } else { |
203 // Disable optimized code. | 205 // Disable optimized code. |
204 const Code& optimized_code = Code::Handle(function.code()); | 206 ASSERT(function.HasOptimizedCode()); |
205 ASSERT(optimized_code.is_optimized()); | 207 // Patch entry of optimized code |
206 CodePatcher::PatchEntry(Code::Handle(function.code())); | 208 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
207 if (FLAG_trace_compiler) { | 209 if (FLAG_trace_compiler) { |
208 OS::Print("--> patching entry 0x%x\n", | 210 OS::Print("--> patching entry 0x%x\n", |
209 Code::Handle(function.unoptimized_code()).EntryPoint()); | 211 Code::Handle(function.CurrentCode()).EntryPoint()); |
210 } | 212 } |
211 // Use previously compiled code. | 213 // Use previously compiled code. |
212 function.SetCode(Code::Handle(function.unoptimized_code())); | 214 function.SetCode(Code::Handle(function.unoptimized_code())); |
213 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); | 215 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); |
214 if (FLAG_trace_compiler) { | 216 if (FLAG_trace_compiler) { |
215 OS::Print("--> restoring entry at 0x%x\n", | 217 OS::Print("--> restoring entry at 0x%x\n", |
216 Code::Handle(function.unoptimized_code()).EntryPoint()); | 218 Code::Handle(function.unoptimized_code()).EntryPoint()); |
217 } | 219 } |
218 } | 220 } |
219 } | 221 } |
220 if (FLAG_trace_compiler) { | 222 if (FLAG_trace_compiler) { |
221 OS::Print("--> '%s' entry: 0x%x\n", | 223 OS::Print("--> '%s' entry: 0x%x\n", |
222 function_fullname, Code::Handle(function.code()).EntryPoint()); | 224 function_fullname, |
| 225 Code::Handle(function.CurrentCode()).EntryPoint()); |
223 } | 226 } |
224 if (FLAG_disassemble) { | 227 if (FLAG_disassemble) { |
225 OS::Print("Code for %sfunction '%s' {\n", | 228 OS::Print("Code for %sfunction '%s' {\n", |
226 optimized ? "optimized " : "", function_fullname); | 229 optimized ? "optimized " : "", function_fullname); |
227 const Code& code = Code::Handle(function.code()); | 230 const Code& code = Code::Handle(function.CurrentCode()); |
228 const Instructions& instructions = | 231 const Instructions& instructions = |
229 Instructions::Handle(code.instructions()); | 232 Instructions::Handle(code.instructions()); |
230 uword start = instructions.EntryPoint(); | 233 uword start = instructions.EntryPoint(); |
231 Disassembler::Disassemble(start, start + assembler.CodeSize()); | 234 Disassembler::Disassemble(start, start + assembler.CodeSize()); |
232 OS::Print("}\n"); | 235 OS::Print("}\n"); |
233 OS::Print("Pointer offsets for function: {\n"); | 236 OS::Print("Pointer offsets for function: {\n"); |
234 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { | 237 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { |
235 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 238 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
236 Object& obj = Object::Handle(); | 239 Object& obj = Object::Handle(); |
237 obj = *reinterpret_cast<RawObject**>(addr); | 240 obj = *reinterpret_cast<RawObject**>(addr); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 parsed_function.set_default_parameter_values(Array::Handle()); | 356 parsed_function.set_default_parameter_values(Array::Handle()); |
354 | 357 |
355 Assembler assembler; | 358 Assembler assembler; |
356 CodeGenerator code_gen(&assembler, parsed_function); | 359 CodeGenerator code_gen(&assembler, parsed_function); |
357 code_gen.GenerateCode(); | 360 code_gen.GenerateCode(); |
358 const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler)); | 361 const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler)); |
359 | 362 |
360 func.SetCode(code); | 363 func.SetCode(code); |
361 CodeIndexTable* code_index_table = isolate->code_index_table(); | 364 CodeIndexTable* code_index_table = isolate->code_index_table(); |
362 ASSERT(code_index_table != NULL); | 365 ASSERT(code_index_table != NULL); |
363 code_index_table->AddFunction(func); | 366 code_index_table->AddCode(code); |
364 // TODO(hausner): We need a way to remove these one-time execution | 367 // TODO(hausner): We need a way to remove these one-time execution |
365 // functions from the global code description (PC mapping) tables so | 368 // functions from the global code description (PC mapping) tables so |
366 // we don't pollute the system unnecessarily with stale data. | 369 // we don't pollute the system unnecessarily with stale data. |
367 code_gen.FinalizePcDescriptors(code); | 370 code_gen.FinalizePcDescriptors(code); |
368 code_gen.FinalizeExceptionHandlers(code); | 371 code_gen.FinalizeExceptionHandlers(code); |
369 | 372 |
370 GrowableArray<const Object*> arguments; // no arguments. | 373 GrowableArray<const Object*> arguments; // no arguments. |
371 const Array& kNoArgumentNames = Array::Handle(); | 374 const Array& kNoArgumentNames = Array::Handle(); |
372 result = DartEntry::InvokeStatic(func, | 375 result = DartEntry::InvokeStatic(func, |
373 arguments, | 376 arguments, |
374 kNoArgumentNames); | 377 kNoArgumentNames); |
375 } else { | 378 } else { |
376 result = isolate->object_store()->sticky_error(); | 379 result = isolate->object_store()->sticky_error(); |
377 isolate->object_store()->clear_sticky_error(); | 380 isolate->object_store()->clear_sticky_error(); |
378 } | 381 } |
379 isolate->set_long_jump_base(base); | 382 isolate->set_long_jump_base(base); |
380 return result.raw(); | 383 return result.raw(); |
381 } | 384 } |
382 | 385 |
383 | 386 |
384 } // namespace dart | 387 } // namespace dart |
OLD | NEW |