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

Unified Diff: runtime/vm/compiler.cc

Issue 9169102: Add Dart_PropagateError. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/compiler.cc
===================================================================
--- runtime/vm/compiler.cc (revision 3804)
+++ runtime/vm/compiler.cc (working copy)
@@ -11,7 +11,9 @@
#include "vm/code_patcher.h"
#include "vm/dart_entry.h"
#include "vm/disassembler.h"
+#include "vm/exceptions.h"
#include "vm/flags.h"
+#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/opt_code_generator.h"
@@ -35,7 +37,10 @@
ASSERT(arguments.Count() == kCompileFunctionRuntimeEntry.argument_count());
const Function& function = Function::CheckedHandle(arguments.At(0));
ASSERT(!function.HasCode());
- Compiler::CompileFunction(function);
+ const Error& error = Error::Handle(Compiler::CompileFunction(function));
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
}
@@ -65,223 +70,271 @@
}
-void Compiler::Compile(const Library& library, const Script& script) {
- if (FLAG_trace_compiler) {
- HANDLESCOPE(Isolate::Current());
- const String& script_url = String::Handle(script.url());
- // TODO(iposva): Extract script kind.
- OS::Print("Compiling %s '%s'\n", "", script_url.ToCString());
+RawError* Compiler::Compile(const Library& library, const Script& script) {
+ Isolate* isolate = Isolate::Current();
+ Error& error = Error::Handle();
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ if (FLAG_trace_compiler) {
+ HANDLESCOPE(isolate);
+ const String& script_url = String::Handle(script.url());
+ // TODO(iposva): Extract script kind.
+ OS::Print("Compiling %s '%s'\n", "", script_url.ToCString());
+ }
+ const String& library_key = String::Handle(library.private_key());
+ script.Tokenize(library_key);
+ Parser::ParseCompilationUnit(library, script);
+ } else {
+ error = isolate->object_store()->sticky_error();
+ isolate->object_store()->clear_sticky_error();
}
- const String& library_key = String::Handle(library.private_key());
- script.Tokenize(library_key);
- Parser::ParseCompilationUnit(library, script);
+ isolate->set_long_jump_base(base);
+ return error.raw();
}
-static void CompileFunctionHelper(const Function& function, bool optimized) {
- TIMERSCOPE(time_compilation);
- ParsedFunction parsed_function(function);
- const char* function_fullname = function.ToFullyQualifiedCString();
- if (FLAG_trace_compiler) {
- OS::Print("Compiling %sfunction: '%s' @ token %d\n",
- (optimized ? "optimized " : ""),
- function_fullname,
- function.token_index());
- }
- Parser::ParseFunction(&parsed_function);
- CodeIndexTable* code_index_table = Isolate::Current()->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()));
+static RawError* CompileFunctionHelper(const Function& function,
+ bool optimized) {
+ Isolate* isolate = Isolate::Current();
+ Error& error = Error::Handle();
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ TIMERSCOPE(time_compilation);
+ ParsedFunction parsed_function(function);
+ const char* function_fullname = function.ToFullyQualifiedCString();
if (FLAG_trace_compiler) {
- OS::Print("--> patching entry 0x%x\n",
- Code::Handle(function.unoptimized_code()).EntryPoint());
+ OS::Print("Compiling %sfunction: '%s' @ token %d\n",
+ (optimized ? "optimized " : ""),
+ function_fullname,
+ function.token_index());
}
- } 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);
+ Parser::ParseFunction(&parsed_function);
+ 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();
- 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());
+ 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());
+ }
}
}
- }
- if (FLAG_trace_compiler) {
- OS::Print("--> '%s' entry: 0x%x\n",
- function_fullname, Code::Handle(function.code()).EntryPoint());
- }
- if (FLAG_disassemble) {
- OS::Print("Code for %sfunction '%s' {\n",
- optimized ? "optimized " : "", function_fullname);
- const Code& code = Code::Handle(function.code());
- const Instructions& instructions =
- Instructions::Handle(code.instructions());
- uword start = instructions.EntryPoint();
- Disassembler::Disassemble(start, start + assembler.CodeSize());
- OS::Print("}\n");
- OS::Print("Pointer offsets for function: {\n");
- for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
- const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
- Object& obj = Object::Handle();
- obj = *reinterpret_cast<RawObject**>(addr);
- OS::Print(" %d : 0x%x '%s'\n",
- code.GetPointerOffsetAt(i), addr, obj.ToCString());
+ if (FLAG_trace_compiler) {
+ OS::Print("--> '%s' entry: 0x%x\n",
+ function_fullname, Code::Handle(function.code()).EntryPoint());
}
- OS::Print("}\n");
- OS::Print("PC Descriptors for function '%s' {\n", function_fullname);
- OS::Print("(pc, kind, id, try-index, token-index)\n");
- const PcDescriptors& descriptors =
- PcDescriptors::Handle(code.pc_descriptors());
- OS::Print("%s", descriptors.ToCString());
- OS::Print("}\n");
- OS::Print("Variable Descriptors for function '%s' {\n", function_fullname);
- const LocalVarDescriptors& var_descriptors =
- LocalVarDescriptors::Handle(code.var_descriptors());
- intptr_t var_desc_length =
- var_descriptors.IsNull() ? 0 : var_descriptors.Length();
- String& var_name = String::Handle();
- for (intptr_t i = 0; i < var_desc_length; i++) {
- var_name = var_descriptors.GetName(i);
- intptr_t scope_id, begin_pos, end_pos;
- var_descriptors.GetScopeInfo(i, &scope_id, &begin_pos, &end_pos);
- intptr_t slot = var_descriptors.GetSlotIndex(i);
- OS::Print(" var %s scope %ld (valid %d-%d) offset %ld\n",
- var_name.ToCString(), scope_id, begin_pos, end_pos, slot);
+ if (FLAG_disassemble) {
+ OS::Print("Code for %sfunction '%s' {\n",
+ optimized ? "optimized " : "", function_fullname);
+ const Code& code = Code::Handle(function.code());
+ const Instructions& instructions =
+ Instructions::Handle(code.instructions());
+ uword start = instructions.EntryPoint();
+ Disassembler::Disassemble(start, start + assembler.CodeSize());
+ OS::Print("}\n");
+ OS::Print("Pointer offsets for function: {\n");
+ for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
+ const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
+ Object& obj = Object::Handle();
+ obj = *reinterpret_cast<RawObject**>(addr);
+ OS::Print(" %d : 0x%x '%s'\n",
+ code.GetPointerOffsetAt(i), addr, obj.ToCString());
+ }
+ OS::Print("}\n");
+ OS::Print("PC Descriptors for function '%s' {\n", function_fullname);
+ OS::Print("(pc, kind, id, try-index, token-index)\n");
+ const PcDescriptors& descriptors =
+ PcDescriptors::Handle(code.pc_descriptors());
+ OS::Print("%s", descriptors.ToCString());
+ OS::Print("}\n");
+ OS::Print("Variable Descriptors for function '%s' {\n",
+ function_fullname);
+ const LocalVarDescriptors& var_descriptors =
+ LocalVarDescriptors::Handle(code.var_descriptors());
+ intptr_t var_desc_length =
+ var_descriptors.IsNull() ? 0 : var_descriptors.Length();
+ String& var_name = String::Handle();
+ for (intptr_t i = 0; i < var_desc_length; i++) {
+ var_name = var_descriptors.GetName(i);
+ intptr_t scope_id, begin_pos, end_pos;
+ var_descriptors.GetScopeInfo(i, &scope_id, &begin_pos, &end_pos);
+ intptr_t slot = var_descriptors.GetSlotIndex(i);
+ OS::Print(" var %s scope %ld (valid %d-%d) offset %ld\n",
+ var_name.ToCString(), scope_id, begin_pos, end_pos, slot);
+ }
+ OS::Print("}\n");
+ OS::Print("Exception Handlers for function '%s' {\n", function_fullname);
+ const ExceptionHandlers& handlers =
+ ExceptionHandlers::Handle(code.exception_handlers());
+ OS::Print("%s", handlers.ToCString());
+ OS::Print("}\n");
}
- OS::Print("}\n");
- OS::Print("Exception Handlers for function '%s' {\n", function_fullname);
- const ExceptionHandlers& handlers =
- ExceptionHandlers::Handle(code.exception_handlers());
- OS::Print("%s", handlers.ToCString());
- OS::Print("}\n");
+ } else {
+ // We got an error during compilation.
+ error = isolate->object_store()->sticky_error();
+ isolate->object_store()->clear_sticky_error();
}
+ isolate->set_long_jump_base(base);
+ return error.raw();
}
-void Compiler::CompileFunction(const Function& function) {
- CompileFunctionHelper(function, false);
+RawError* Compiler::CompileFunction(const Function& function) {
+ return CompileFunctionHelper(function, false);
}
-void Compiler::CompileOptimizedFunction(const Function& function) {
- CompileFunctionHelper(function, true);
+RawError* Compiler::CompileOptimizedFunction(const Function& function) {
+ return CompileFunctionHelper(function, true);
}
-void Compiler::CompileAllFunctions(const Class& cls) {
- Array& functions = Array::Handle(cls.functions());
- Function& func = Function::Handle();
- for (int i = 0; i < functions.Length(); i++) {
- func ^= functions.At(i);
- ASSERT(!func.IsNull());
- if (!func.HasCode() && !func.IsAbstract()) {
- CompileFunction(func);
+RawError* Compiler::CompileAllFunctions(const Class& cls) {
+ Isolate* isolate = Isolate::Current();
+ Error& error = Error::Handle();
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ Array& functions = Array::Handle(cls.functions());
+ Function& func = Function::Handle();
+ for (int i = 0; i < functions.Length(); i++) {
+ func ^= functions.At(i);
+ ASSERT(!func.IsNull());
+ if (!func.HasCode() && !func.IsAbstract()) {
+ const Error& error = Error::Handle(CompileFunction(func));
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ }
}
+ } else {
+ error = isolate->object_store()->sticky_error();
+ isolate->object_store()->clear_sticky_error();
}
+ isolate->set_long_jump_base(base);
+ return error.raw();
}
-RawInstance* Compiler::ExecuteOnce(SequenceNode* fragment) {
- if (FLAG_trace_compiler) {
- OS::Print("compiling expression: ");
- AstPrinter::PrintNode(fragment);
- }
+RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
+ Isolate* isolate = Isolate::Current();
+ Object& result = Object::Handle();
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ if (FLAG_trace_compiler) {
+ OS::Print("compiling expression: ");
+ AstPrinter::PrintNode(fragment);
+ }
- // Create a dummy function object for the code generator.
- const char* kEvalConst = "eval_const";
- const Function& func = Function::Handle(Function::New(
- String::Handle(String::NewSymbol(kEvalConst)),
- RawFunction::kConstImplicitGetter,
- true, // static function.
- false, // not const function.
- fragment->token_index()));
+ // Create a dummy function object for the code generator.
+ const char* kEvalConst = "eval_const";
+ const Function& func = Function::Handle(Function::New(
+ String::Handle(String::NewSymbol(kEvalConst)),
+ RawFunction::kConstImplicitGetter,
+ true, // static function.
+ false, // not const function.
+ fragment->token_index()));
- func.set_result_type(Type::Handle(Type::DynamicType()));
- func.set_num_fixed_parameters(0);
- func.set_num_optional_parameters(0);
+ func.set_result_type(Type::Handle(Type::DynamicType()));
+ func.set_num_fixed_parameters(0);
+ func.set_num_optional_parameters(0);
- // The function needs to be associated with a named Class: the interface
- // Function fits the bill.
- func.set_owner(Class::Handle(
- Type::Handle(Type::FunctionInterface()).type_class()));
+ // The function needs to be associated with a named Class: the interface
+ // Function fits the bill.
+ func.set_owner(Class::Handle(
+ Type::Handle(Type::FunctionInterface()).type_class()));
- // We compile the function here, even though InvokeStatic() below
- // would compile func automatically. We are checking fewer invariants
- // here.
- ParsedFunction parsed_function(func);
- parsed_function.set_node_sequence(fragment);
- parsed_function.set_default_parameter_values(Array::Handle());
+ // We compile the function here, even though InvokeStatic() below
+ // would compile func automatically. We are checking fewer invariants
+ // here.
+ ParsedFunction parsed_function(func);
+ parsed_function.set_node_sequence(fragment);
+ parsed_function.set_default_parameter_values(Array::Handle());
- Assembler assembler;
- CodeGenerator code_gen(&assembler, parsed_function);
- code_gen.GenerateCode();
- const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler));
+ Assembler assembler;
+ CodeGenerator code_gen(&assembler, parsed_function);
+ code_gen.GenerateCode();
+ const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler));
- func.SetCode(code);
- CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
- ASSERT(code_index_table != NULL);
- code_index_table->AddFunction(func);
- // TODO(hausner): We need a way to remove these one-time execution
- // functions from the global code description (PC mapping) tables so
- // we don't pollute the system unnecessarily with stale data.
- code_gen.FinalizePcDescriptors(code);
- code_gen.FinalizeExceptionHandlers(code);
+ func.SetCode(code);
+ CodeIndexTable* code_index_table = isolate->code_index_table();
+ ASSERT(code_index_table != NULL);
+ code_index_table->AddFunction(func);
+ // TODO(hausner): We need a way to remove these one-time execution
+ // functions from the global code description (PC mapping) tables so
+ // we don't pollute the system unnecessarily with stale data.
+ code_gen.FinalizePcDescriptors(code);
+ code_gen.FinalizeExceptionHandlers(code);
- GrowableArray<const Object*> arguments; // no arguments.
- const Array& kNoArgumentNames = Array::Handle();
- Instance& result = Instance::Handle(
- DartEntry::InvokeStatic(func,
- arguments,
- kNoArgumentNames));
- if (result.IsUnhandledException()) {
- // TODO(srdjan): implement proper exit from compiler.
- UNIMPLEMENTED();
+ GrowableArray<const Object*> arguments; // no arguments.
+ const Array& kNoArgumentNames = Array::Handle();
+ result = DartEntry::InvokeStatic(func,
+ arguments,
+ kNoArgumentNames);
+ } else {
+ result = isolate->object_store()->sticky_error();
+ isolate->object_store()->clear_sticky_error();
}
+ isolate->set_long_jump_base(base);
return result.raw();
}
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698