| 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 |