| Index: runtime/vm/compiler.cc
|
| diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
|
| index 3c019bbf91e72d3ccd80c2822c4d6a6d4708e373..eba7cdfedb738acafeff2f248e332349471b7cc3 100644
|
| --- a/runtime/vm/compiler.cc
|
| +++ b/runtime/vm/compiler.cc
|
| @@ -123,6 +123,11 @@ static RawError* CompileFunctionHelper(const Function& function,
|
| function.token_index());
|
| }
|
| Parser::ParseFunction(&parsed_function);
|
| +
|
| + CodeIndexTable* code_index_table = isolate->code_index_table();
|
| + ASSERT(code_index_table != NULL);
|
| + int code_size = -1; // Assembled code size needed if --disassemble.
|
| + bool is_compiled = false;
|
| if (FLAG_use_new_compiler) {
|
| ASSERT(!optimized);
|
| LongJump* old_base = isolate->long_jump_base();
|
| @@ -132,17 +137,23 @@ static RawError* CompileFunctionHelper(const Function& function,
|
| FlowGraphBuilder graph_builder(parsed_function);
|
| graph_builder.BuildGraph();
|
|
|
| - // Try to compile on x64 (only for now).
|
| -#ifdef TARGET_ARCH_X64
|
| - // TODO(kmillikin): Implement or stub out class FlowGraphCompiler
|
| - // for other architectures and remove the unsightly ifdef.
|
| Assembler assembler;
|
| FlowGraphCompiler graph_compiler(&assembler,
|
| parsed_function,
|
| graph_builder.blocks());
|
| graph_compiler.CompileGraph();
|
| -#endif
|
| -
|
| + const Code& code =
|
| + Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
|
| + code.set_is_optimized(false);
|
| + graph_compiler.FinalizePcDescriptors(code);
|
| + graph_compiler.FinalizeVarDescriptors(code);
|
| + graph_compiler.FinalizeExceptionHandlers(code);
|
| + function.set_unoptimized_code(code);
|
| + function.SetCode(code);
|
| + ASSERT(CodePatcher::CodeIsPatchable(code));
|
| + code_index_table->AddFunction(function);
|
| + is_compiled = true;
|
| + code_size = assembler.CodeSize();
|
| } else {
|
| // We bailed out.
|
| Error& bailout_error = Error::Handle(
|
| @@ -153,69 +164,72 @@ static RawError* CompileFunctionHelper(const Function& function,
|
| }
|
| }
|
| isolate->set_long_jump_base(old_base);
|
| - // Currently, always fails and falls through to the old compiler.
|
| }
|
| - CodeIndexTable* code_index_table = isolate->code_index_table();
|
| - ASSERT(code_index_table != NULL);
|
| - Assembler assembler;
|
| - if (optimized) {
|
| - // Transition to optimized code only from unoptimized code ... for now.
|
| - ASSERT(function.HasCode());
|
| - ASSERT(!Code::Handle(function.code()).is_optimized());
|
| - // Do not use type feedback to optimize a function that was deoptimized.
|
| - if (parsed_function.function().deoptimization_counter() <
|
| - FLAG_deoptimization_counter_threshold) {
|
| - ExtractTypeFeedback(Code::Handle(parsed_function.function().code()),
|
| - parsed_function.node_sequence());
|
| - }
|
| - OptimizingCodeGenerator code_gen(&assembler, parsed_function);
|
| - code_gen.GenerateCode();
|
| - Code& code = Code::Handle(
|
| - Code::FinalizeCode(function_fullname, &assembler));
|
| - code.set_is_optimized(true);
|
| - code_gen.FinalizePcDescriptors(code);
|
| - code_gen.FinalizeExceptionHandlers(code);
|
| - function.SetCode(code);
|
| - code_index_table->AddFunction(function);
|
| - CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
|
| - if (FLAG_trace_compiler) {
|
| - OS::Print("--> patching entry 0x%x\n",
|
| - Code::Handle(function.unoptimized_code()).EntryPoint());
|
| - }
|
| - } else {
|
| - // Unoptimized code.
|
| - if (Code::Handle(function.unoptimized_code()).IsNull()) {
|
| - ASSERT(Code::Handle(function.code()).IsNull());
|
| - // Compiling first time.
|
| - CodeGenerator code_gen(&assembler, parsed_function);
|
| +
|
| + if (!is_compiled) {
|
| + Assembler assembler;
|
| + if (optimized) {
|
| + // Transition to optimized code only from unoptimized code ...
|
| + // for now.
|
| + ASSERT(function.HasCode());
|
| + ASSERT(!Code::Handle(function.code()).is_optimized());
|
| + // Do not use type feedback to optimize a function that was
|
| + // deoptimized.
|
| + if (parsed_function.function().deoptimization_counter() <
|
| + FLAG_deoptimization_counter_threshold) {
|
| + ExtractTypeFeedback(Code::Handle(parsed_function.function().code()),
|
| + parsed_function.node_sequence());
|
| + }
|
| + OptimizingCodeGenerator code_gen(&assembler, parsed_function);
|
| code_gen.GenerateCode();
|
| - const Code& code =
|
| - Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
|
| - code.set_is_optimized(false);
|
| + Code& code = Code::Handle(
|
| + Code::FinalizeCode(function_fullname, &assembler));
|
| + code.set_is_optimized(true);
|
| code_gen.FinalizePcDescriptors(code);
|
| - code_gen.FinalizeVarDescriptors(code);
|
| code_gen.FinalizeExceptionHandlers(code);
|
| - function.set_unoptimized_code(code);
|
| function.SetCode(code);
|
| - ASSERT(CodePatcher::CodeIsPatchable(code));
|
| code_index_table->AddFunction(function);
|
| - } else {
|
| - // Disable optimized code.
|
| - const Code& optimized_code = Code::Handle(function.code());
|
| - ASSERT(optimized_code.is_optimized());
|
| - CodePatcher::PatchEntry(Code::Handle(function.code()));
|
| + CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
|
| if (FLAG_trace_compiler) {
|
| OS::Print("--> patching entry 0x%x\n",
|
| Code::Handle(function.unoptimized_code()).EntryPoint());
|
| }
|
| - // Use previously compiled code.
|
| - function.SetCode(Code::Handle(function.unoptimized_code()));
|
| - CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
|
| - if (FLAG_trace_compiler) {
|
| - OS::Print("--> restoring entry at 0x%x\n",
|
| - Code::Handle(function.unoptimized_code()).EntryPoint());
|
| + } else {
|
| + // Unoptimized code.
|
| + if (Code::Handle(function.unoptimized_code()).IsNull()) {
|
| + ASSERT(Code::Handle(function.code()).IsNull());
|
| + // Compiling first time.
|
| + CodeGenerator code_gen(&assembler, parsed_function);
|
| + code_gen.GenerateCode();
|
| + const Code& code =
|
| + Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
|
| + code.set_is_optimized(false);
|
| + code_gen.FinalizePcDescriptors(code);
|
| + code_gen.FinalizeVarDescriptors(code);
|
| + code_gen.FinalizeExceptionHandlers(code);
|
| + function.set_unoptimized_code(code);
|
| + function.SetCode(code);
|
| + ASSERT(CodePatcher::CodeIsPatchable(code));
|
| + code_index_table->AddFunction(function);
|
| + } else {
|
| + // Disable optimized code.
|
| + const Code& optimized_code = Code::Handle(function.code());
|
| + ASSERT(optimized_code.is_optimized());
|
| + CodePatcher::PatchEntry(Code::Handle(function.code()));
|
| + if (FLAG_trace_compiler) {
|
| + OS::Print("--> patching entry 0x%x\n",
|
| + Code::Handle(function.unoptimized_code()).EntryPoint());
|
| + }
|
| + // Use previously compiled code.
|
| + function.SetCode(Code::Handle(function.unoptimized_code()));
|
| + CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
|
| + if (FLAG_trace_compiler) {
|
| + OS::Print("--> restoring entry at 0x%x\n",
|
| + Code::Handle(function.unoptimized_code()).EntryPoint());
|
| + }
|
| }
|
| }
|
| + code_size = assembler.CodeSize();
|
| }
|
| if (FLAG_trace_compiler) {
|
| OS::Print("--> '%s' entry: 0x%x\n",
|
| @@ -228,7 +242,7 @@ static RawError* CompileFunctionHelper(const Function& function,
|
| const Instructions& instructions =
|
| Instructions::Handle(code.instructions());
|
| uword start = instructions.EntryPoint();
|
| - Disassembler::Disassemble(start, start + assembler.CodeSize());
|
| + Disassembler::Disassemble(start, start + code_size);
|
| OS::Print("}\n");
|
| OS::Print("Pointer offsets for function: {\n");
|
| for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
|
|
|