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

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

Issue 9314053: Revert Dart_PropagateError until I can track down the problems in (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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/compiler.h ('k') | runtime/vm/cpu.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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"
11 #include "vm/code_patcher.h" 11 #include "vm/code_patcher.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/disassembler.h" 13 #include "vm/disassembler.h"
14 #include "vm/exceptions.h"
15 #include "vm/flags.h" 14 #include "vm/flags.h"
16 #include "vm/longjump.h"
17 #include "vm/object.h" 15 #include "vm/object.h"
18 #include "vm/object_store.h" 16 #include "vm/object_store.h"
19 #include "vm/opt_code_generator.h" 17 #include "vm/opt_code_generator.h"
20 #include "vm/os.h" 18 #include "vm/os.h"
21 #include "vm/parser.h" 19 #include "vm/parser.h"
22 #include "vm/scanner.h" 20 #include "vm/scanner.h"
23 #include "vm/timer.h" 21 #include "vm/timer.h"
24 22
25 namespace dart { 23 namespace dart {
26 24
27 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code."); 25 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code.");
28 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); 26 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
29 DEFINE_FLAG(int, deoptimization_counter_threshold, 5, 27 DEFINE_FLAG(int, deoptimization_counter_threshold, 5,
30 "How many times we allow deoptimization before we disallow" 28 "How many times we allow deoptimization before we disallow"
31 " certain optimizations"); 29 " certain optimizations");
32 30
33 31
34 // Compile a function. Should call only if the function has not been compiled. 32 // Compile a function. Should call only if the function has not been compiled.
35 // Arg0: function object. 33 // Arg0: function object.
36 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { 34 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
37 ASSERT(arguments.Count() == kCompileFunctionRuntimeEntry.argument_count()); 35 ASSERT(arguments.Count() == kCompileFunctionRuntimeEntry.argument_count());
38 const Function& function = Function::CheckedHandle(arguments.At(0)); 36 const Function& function = Function::CheckedHandle(arguments.At(0));
39 ASSERT(!function.HasCode()); 37 ASSERT(!function.HasCode());
40 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 38 Compiler::CompileFunction(function);
41 if (!error.IsNull()) {
42 Exceptions::PropagateError(error);
43 }
44 } 39 }
45 40
46 41
47 // Extracts IC data associated with a node id. 42 // Extracts IC data associated with a node id.
48 // TODO(srdjan): Check performance impact of node id search loop. 43 // TODO(srdjan): Check performance impact of node id search loop.
49 static void ExtractTypeFeedback(const Code& code, 44 static void ExtractTypeFeedback(const Code& code,
50 SequenceNode* sequence_node) { 45 SequenceNode* sequence_node) {
51 ASSERT(!code.IsNull() && !code.is_optimized()); 46 ASSERT(!code.IsNull() && !code.is_optimized());
52 GrowableArray<AstNode*> all_nodes; 47 GrowableArray<AstNode*> all_nodes;
53 sequence_node->CollectAllNodes(&all_nodes); 48 sequence_node->CollectAllNodes(&all_nodes);
54 GrowableArray<intptr_t> node_ids; 49 GrowableArray<intptr_t> node_ids;
55 GrowableArray<const Array*> arrays; 50 GrowableArray<const Array*> arrays;
56 code.ExtractIcDataArraysAtCalls(&node_ids, &arrays); 51 code.ExtractIcDataArraysAtCalls(&node_ids, &arrays);
57 for (intptr_t i = 0; i < node_ids.length(); i++) { 52 for (intptr_t i = 0; i < node_ids.length(); i++) {
58 intptr_t node_id = node_ids[i]; 53 intptr_t node_id = node_ids[i];
59 bool found_node = false; 54 bool found_node = false;
60 for (intptr_t n = 0; n < all_nodes.length(); n++) { 55 for (intptr_t n = 0; n < all_nodes.length(); n++) {
61 if (all_nodes[n]->HasId(node_id)) { 56 if (all_nodes[n]->HasId(node_id)) {
62 found_node = true; 57 found_node = true;
63 // Make sure we assign ic data array only once. 58 // Make sure we assign ic data array only once.
64 ASSERT(all_nodes[n]->ICDataAtId(node_id).NumberOfChecks() == 0); 59 ASSERT(all_nodes[n]->ICDataAtId(node_id).NumberOfChecks() == 0);
65 all_nodes[n]->SetIcDataArrayAtId(node_id, *arrays[i]); 60 all_nodes[n]->SetIcDataArrayAtId(node_id, *arrays[i]);
66 } 61 }
67 } 62 }
68 ASSERT(found_node); 63 ASSERT(found_node);
69 } 64 }
70 } 65 }
71 66
72 67
73 RawError* Compiler::Compile(const Library& library, const Script& script) { 68 void Compiler::Compile(const Library& library, const Script& script) {
74 Isolate* isolate = Isolate::Current(); 69 if (FLAG_trace_compiler) {
75 Error& error = Error::Handle(); 70 HANDLESCOPE(Isolate::Current());
76 LongJump* base = isolate->long_jump_base(); 71 const String& script_url = String::Handle(script.url());
77 LongJump jump; 72 // TODO(iposva): Extract script kind.
78 isolate->set_long_jump_base(&jump); 73 OS::Print("Compiling %s '%s'\n", "", script_url.ToCString());
79 if (setjmp(*jump.Set()) == 0) { 74 }
75 const String& library_key = String::Handle(library.private_key());
76 script.Tokenize(library_key);
77 Parser::ParseCompilationUnit(library, script);
78 }
79
80
81 static void CompileFunctionHelper(const Function& function, bool optimized) {
82 TIMERSCOPE(time_compilation);
83 ParsedFunction parsed_function(function);
84 const char* function_fullname = function.ToFullyQualifiedCString();
85 if (FLAG_trace_compiler) {
86 OS::Print("Compiling %sfunction: '%s' @ token %d\n",
87 (optimized ? "optimized " : ""),
88 function_fullname,
89 function.token_index());
90 }
91 Parser::ParseFunction(&parsed_function);
92 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
93 ASSERT(code_index_table != NULL);
94 Assembler assembler;
95 if (optimized) {
96 // Transition to optimized code only from unoptimized code ... for now.
97 ASSERT(function.HasCode());
98 ASSERT(!Code::Handle(function.code()).is_optimized());
99 // Do not use type feedback to optimize a function that was deoptimized.
100 if (parsed_function.function().deoptimization_counter() <
101 FLAG_deoptimization_counter_threshold) {
102 ExtractTypeFeedback(Code::Handle(parsed_function.function().code()),
103 parsed_function.node_sequence());
104 }
105 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
106 code_gen.GenerateCode();
107 Code& code = Code::Handle(
108 Code::FinalizeCode(function_fullname, &assembler));
109 code.set_is_optimized(true);
110 code_gen.FinalizePcDescriptors(code);
111 code_gen.FinalizeExceptionHandlers(code);
112 function.SetCode(code);
113 code_index_table->AddFunction(function);
114 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
80 if (FLAG_trace_compiler) { 115 if (FLAG_trace_compiler) {
81 HANDLESCOPE(isolate); 116 OS::Print("--> patching entry 0x%x\n",
82 const String& script_url = String::Handle(script.url()); 117 Code::Handle(function.unoptimized_code()).EntryPoint());
83 // TODO(iposva): Extract script kind. 118 }
84 OS::Print("Compiling %s '%s'\n", "", script_url.ToCString());
85 }
86 const String& library_key = String::Handle(library.private_key());
87 script.Tokenize(library_key);
88 Parser::ParseCompilationUnit(library, script);
89 } else { 119 } else {
90 error = isolate->object_store()->sticky_error(); 120 // Unoptimized code.
91 isolate->object_store()->clear_sticky_error(); 121 if (Code::Handle(function.unoptimized_code()).IsNull()) {
92 } 122 ASSERT(Code::Handle(function.code()).IsNull());
93 isolate->set_long_jump_base(base); 123 // Compiling first time.
94 return error.raw(); 124 CodeGenerator code_gen(&assembler, parsed_function);
95 }
96
97
98 static RawError* CompileFunctionHelper(const Function& function,
99 bool optimized) {
100 Isolate* isolate = Isolate::Current();
101 Error& error = Error::Handle();
102 LongJump* base = isolate->long_jump_base();
103 LongJump jump;
104 isolate->set_long_jump_base(&jump);
105 if (setjmp(*jump.Set()) == 0) {
106 TIMERSCOPE(time_compilation);
107 ParsedFunction parsed_function(function);
108 const char* function_fullname = function.ToFullyQualifiedCString();
109 if (FLAG_trace_compiler) {
110 OS::Print("Compiling %sfunction: '%s' @ token %d\n",
111 (optimized ? "optimized " : ""),
112 function_fullname,
113 function.token_index());
114 }
115 Parser::ParseFunction(&parsed_function);
116 CodeIndexTable* code_index_table = isolate->code_index_table();
117 ASSERT(code_index_table != NULL);
118 Assembler assembler;
119 if (optimized) {
120 // Transition to optimized code only from unoptimized code ... for now.
121 ASSERT(function.HasCode());
122 ASSERT(!Code::Handle(function.code()).is_optimized());
123 // Do not use type feedback to optimize a function that was deoptimized.
124 if (parsed_function.function().deoptimization_counter() <
125 FLAG_deoptimization_counter_threshold) {
126 ExtractTypeFeedback(Code::Handle(parsed_function.function().code()),
127 parsed_function.node_sequence());
128 }
129 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
130 code_gen.GenerateCode(); 125 code_gen.GenerateCode();
131 Code& code = Code::Handle( 126 const Code& code =
132 Code::FinalizeCode(function_fullname, &assembler)); 127 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
133 code.set_is_optimized(true); 128 code.set_is_optimized(false);
134 code_gen.FinalizePcDescriptors(code); 129 code_gen.FinalizePcDescriptors(code);
130 code_gen.FinalizeVarDescriptors(code);
135 code_gen.FinalizeExceptionHandlers(code); 131 code_gen.FinalizeExceptionHandlers(code);
132 function.set_unoptimized_code(code);
136 function.SetCode(code); 133 function.SetCode(code);
134 ASSERT(CodePatcher::CodeIsPatchable(code));
137 code_index_table->AddFunction(function); 135 code_index_table->AddFunction(function);
138 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); 136 } else {
137 // Disable optimized code.
138 const Code& optimized_code = Code::Handle(function.code());
139 ASSERT(optimized_code.is_optimized());
140 CodePatcher::PatchEntry(Code::Handle(function.code()));
139 if (FLAG_trace_compiler) { 141 if (FLAG_trace_compiler) {
140 OS::Print("--> patching entry 0x%x\n", 142 OS::Print("--> patching entry 0x%x\n",
141 Code::Handle(function.unoptimized_code()).EntryPoint()); 143 Code::Handle(function.unoptimized_code()).EntryPoint());
142 } 144 }
143 } else { 145 // Use previously compiled code.
144 // Unoptimized code. 146 function.SetCode(Code::Handle(function.unoptimized_code()));
145 if (Code::Handle(function.unoptimized_code()).IsNull()) { 147 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
146 ASSERT(Code::Handle(function.code()).IsNull()); 148 if (FLAG_trace_compiler) {
147 // Compiling first time. 149 OS::Print("--> restoring entry at 0x%x\n",
148 CodeGenerator code_gen(&assembler, parsed_function); 150 Code::Handle(function.unoptimized_code()).EntryPoint());
149 code_gen.GenerateCode();
150 const Code& code =
151 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
152 code.set_is_optimized(false);
153 code_gen.FinalizePcDescriptors(code);
154 code_gen.FinalizeVarDescriptors(code);
155 code_gen.FinalizeExceptionHandlers(code);
156 function.set_unoptimized_code(code);
157 function.SetCode(code);
158 ASSERT(CodePatcher::CodeIsPatchable(code));
159 code_index_table->AddFunction(function);
160 } else {
161 // Disable optimized code.
162 const Code& optimized_code = Code::Handle(function.code());
163 ASSERT(optimized_code.is_optimized());
164 CodePatcher::PatchEntry(Code::Handle(function.code()));
165 if (FLAG_trace_compiler) {
166 OS::Print("--> patching entry 0x%x\n",
167 Code::Handle(function.unoptimized_code()).EntryPoint());
168 }
169 // Use previously compiled code.
170 function.SetCode(Code::Handle(function.unoptimized_code()));
171 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
172 if (FLAG_trace_compiler) {
173 OS::Print("--> restoring entry at 0x%x\n",
174 Code::Handle(function.unoptimized_code()).EntryPoint());
175 }
176 } 151 }
177 } 152 }
178 if (FLAG_trace_compiler) { 153 }
179 OS::Print("--> '%s' entry: 0x%x\n", 154 if (FLAG_trace_compiler) {
180 function_fullname, Code::Handle(function.code()).EntryPoint()); 155 OS::Print("--> '%s' entry: 0x%x\n",
181 } 156 function_fullname, Code::Handle(function.code()).EntryPoint());
182 if (FLAG_disassemble) { 157 }
183 OS::Print("Code for %sfunction '%s' {\n", 158 if (FLAG_disassemble) {
184 optimized ? "optimized " : "", function_fullname); 159 OS::Print("Code for %sfunction '%s' {\n",
185 const Code& code = Code::Handle(function.code()); 160 optimized ? "optimized " : "", function_fullname);
186 const Instructions& instructions = 161 const Code& code = Code::Handle(function.code());
187 Instructions::Handle(code.instructions()); 162 const Instructions& instructions =
188 uword start = instructions.EntryPoint(); 163 Instructions::Handle(code.instructions());
189 Disassembler::Disassemble(start, start + assembler.CodeSize()); 164 uword start = instructions.EntryPoint();
190 OS::Print("}\n"); 165 Disassembler::Disassemble(start, start + assembler.CodeSize());
191 OS::Print("Pointer offsets for function: {\n"); 166 OS::Print("}\n");
192 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { 167 OS::Print("Pointer offsets for function: {\n");
193 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); 168 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
194 Object& obj = Object::Handle(); 169 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
195 obj = *reinterpret_cast<RawObject**>(addr); 170 Object& obj = Object::Handle();
196 OS::Print(" %d : 0x%x '%s'\n", 171 obj = *reinterpret_cast<RawObject**>(addr);
197 code.GetPointerOffsetAt(i), addr, obj.ToCString()); 172 OS::Print(" %d : 0x%x '%s'\n",
198 } 173 code.GetPointerOffsetAt(i), addr, obj.ToCString());
199 OS::Print("}\n"); 174 }
200 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); 175 OS::Print("}\n");
201 OS::Print("(pc, kind, id, try-index, token-index)\n"); 176 OS::Print("PC Descriptors for function '%s' {\n", function_fullname);
202 const PcDescriptors& descriptors = 177 OS::Print("(pc, kind, id, try-index, token-index)\n");
203 PcDescriptors::Handle(code.pc_descriptors()); 178 const PcDescriptors& descriptors =
204 OS::Print("%s", descriptors.ToCString()); 179 PcDescriptors::Handle(code.pc_descriptors());
205 OS::Print("}\n"); 180 OS::Print("%s", descriptors.ToCString());
206 OS::Print("Variable Descriptors for function '%s' {\n", 181 OS::Print("}\n");
207 function_fullname); 182 OS::Print("Variable Descriptors for function '%s' {\n", function_fullname);
208 const LocalVarDescriptors& var_descriptors = 183 const LocalVarDescriptors& var_descriptors =
209 LocalVarDescriptors::Handle(code.var_descriptors()); 184 LocalVarDescriptors::Handle(code.var_descriptors());
210 intptr_t var_desc_length = 185 intptr_t var_desc_length =
211 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); 186 var_descriptors.IsNull() ? 0 : var_descriptors.Length();
212 String& var_name = String::Handle(); 187 String& var_name = String::Handle();
213 for (intptr_t i = 0; i < var_desc_length; i++) { 188 for (intptr_t i = 0; i < var_desc_length; i++) {
214 var_name = var_descriptors.GetName(i); 189 var_name = var_descriptors.GetName(i);
215 intptr_t scope_id, begin_pos, end_pos; 190 intptr_t scope_id, begin_pos, end_pos;
216 var_descriptors.GetScopeInfo(i, &scope_id, &begin_pos, &end_pos); 191 var_descriptors.GetScopeInfo(i, &scope_id, &begin_pos, &end_pos);
217 intptr_t slot = var_descriptors.GetSlotIndex(i); 192 intptr_t slot = var_descriptors.GetSlotIndex(i);
218 OS::Print(" var %s scope %ld (valid %d-%d) offset %ld\n", 193 OS::Print(" var %s scope %ld (valid %d-%d) offset %ld\n",
219 var_name.ToCString(), scope_id, begin_pos, end_pos, slot); 194 var_name.ToCString(), scope_id, begin_pos, end_pos, slot);
220 } 195 }
221 OS::Print("}\n"); 196 OS::Print("}\n");
222 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); 197 OS::Print("Exception Handlers for function '%s' {\n", function_fullname);
223 const ExceptionHandlers& handlers = 198 const ExceptionHandlers& handlers =
224 ExceptionHandlers::Handle(code.exception_handlers()); 199 ExceptionHandlers::Handle(code.exception_handlers());
225 OS::Print("%s", handlers.ToCString()); 200 OS::Print("%s", handlers.ToCString());
226 OS::Print("}\n"); 201 OS::Print("}\n");
227 } 202 }
228 } else { 203 }
229 // We got an error during compilation. 204
230 error = isolate->object_store()->sticky_error(); 205
231 isolate->object_store()->clear_sticky_error(); 206 void Compiler::CompileFunction(const Function& function) {
232 } 207 CompileFunctionHelper(function, false);
233 isolate->set_long_jump_base(base); 208 }
234 return error.raw(); 209
235 } 210
236 211 void Compiler::CompileOptimizedFunction(const Function& function) {
237 212 CompileFunctionHelper(function, true);
238 RawError* Compiler::CompileFunction(const Function& function) { 213 }
239 return CompileFunctionHelper(function, false); 214
240 } 215
241 216 void Compiler::CompileAllFunctions(const Class& cls) {
242 217 Array& functions = Array::Handle(cls.functions());
243 RawError* Compiler::CompileOptimizedFunction(const Function& function) { 218 Function& func = Function::Handle();
244 return CompileFunctionHelper(function, true); 219 for (int i = 0; i < functions.Length(); i++) {
245 } 220 func ^= functions.At(i);
246 221 ASSERT(!func.IsNull());
247 222 if (!func.HasCode() && !func.IsAbstract()) {
248 RawError* Compiler::CompileAllFunctions(const Class& cls) { 223 CompileFunction(func);
249 Isolate* isolate = Isolate::Current(); 224 }
250 Error& error = Error::Handle(); 225 }
251 LongJump* base = isolate->long_jump_base(); 226 }
252 LongJump jump; 227
253 isolate->set_long_jump_base(&jump); 228
254 if (setjmp(*jump.Set()) == 0) { 229 RawInstance* Compiler::ExecuteOnce(SequenceNode* fragment) {
255 Array& functions = Array::Handle(cls.functions()); 230 if (FLAG_trace_compiler) {
256 Function& func = Function::Handle(); 231 OS::Print("compiling expression: ");
257 for (int i = 0; i < functions.Length(); i++) { 232 AstPrinter::PrintNode(fragment);
258 func ^= functions.At(i); 233 }
259 ASSERT(!func.IsNull()); 234
260 if (!func.HasCode() && !func.IsAbstract()) { 235 // Create a dummy function object for the code generator.
261 const Error& error = Error::Handle(CompileFunction(func)); 236 const char* kEvalConst = "eval_const";
262 if (!error.IsNull()) { 237 const Function& func = Function::Handle(Function::New(
263 return error.raw(); 238 String::Handle(String::NewSymbol(kEvalConst)),
264 } 239 RawFunction::kConstImplicitGetter,
265 } 240 true, // static function.
266 } 241 false, // not const function.
267 } else { 242 fragment->token_index()));
268 error = isolate->object_store()->sticky_error(); 243
269 isolate->object_store()->clear_sticky_error(); 244 func.set_result_type(Type::Handle(Type::DynamicType()));
270 } 245 func.set_num_fixed_parameters(0);
271 isolate->set_long_jump_base(base); 246 func.set_num_optional_parameters(0);
272 return error.raw(); 247
273 } 248 // The function needs to be associated with a named Class: the interface
274 249 // Function fits the bill.
275 250 func.set_owner(Class::Handle(
276 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { 251 Type::Handle(Type::FunctionInterface()).type_class()));
277 Isolate* isolate = Isolate::Current(); 252
278 Object& result = Object::Handle(); 253 // We compile the function here, even though InvokeStatic() below
279 LongJump* base = isolate->long_jump_base(); 254 // would compile func automatically. We are checking fewer invariants
280 LongJump jump; 255 // here.
281 isolate->set_long_jump_base(&jump); 256 ParsedFunction parsed_function(func);
282 if (setjmp(*jump.Set()) == 0) { 257 parsed_function.set_node_sequence(fragment);
283 if (FLAG_trace_compiler) { 258 parsed_function.set_default_parameter_values(Array::Handle());
284 OS::Print("compiling expression: "); 259
285 AstPrinter::PrintNode(fragment); 260 Assembler assembler;
286 } 261 CodeGenerator code_gen(&assembler, parsed_function);
287 262 code_gen.GenerateCode();
288 // Create a dummy function object for the code generator. 263 const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler));
289 const char* kEvalConst = "eval_const"; 264
290 const Function& func = Function::Handle(Function::New( 265 func.SetCode(code);
291 String::Handle(String::NewSymbol(kEvalConst)), 266 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
292 RawFunction::kConstImplicitGetter, 267 ASSERT(code_index_table != NULL);
293 true, // static function. 268 code_index_table->AddFunction(func);
294 false, // not const function. 269 // TODO(hausner): We need a way to remove these one-time execution
295 fragment->token_index())); 270 // functions from the global code description (PC mapping) tables so
296 271 // we don't pollute the system unnecessarily with stale data.
297 func.set_result_type(Type::Handle(Type::DynamicType())); 272 code_gen.FinalizePcDescriptors(code);
298 func.set_num_fixed_parameters(0); 273 code_gen.FinalizeExceptionHandlers(code);
299 func.set_num_optional_parameters(0); 274
300 275 GrowableArray<const Object*> arguments; // no arguments.
301 // The function needs to be associated with a named Class: the interface 276 const Array& kNoArgumentNames = Array::Handle();
302 // Function fits the bill. 277 Instance& result = Instance::Handle(
303 func.set_owner(Class::Handle( 278 DartEntry::InvokeStatic(func,
304 Type::Handle(Type::FunctionInterface()).type_class())); 279 arguments,
305 280 kNoArgumentNames));
306 // We compile the function here, even though InvokeStatic() below 281 if (result.IsUnhandledException()) {
307 // would compile func automatically. We are checking fewer invariants 282 // TODO(srdjan): implement proper exit from compiler.
308 // here. 283 UNIMPLEMENTED();
309 ParsedFunction parsed_function(func); 284 }
310 parsed_function.set_node_sequence(fragment);
311 parsed_function.set_default_parameter_values(Array::Handle());
312
313 Assembler assembler;
314 CodeGenerator code_gen(&assembler, parsed_function);
315 code_gen.GenerateCode();
316 const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler));
317
318 func.SetCode(code);
319 CodeIndexTable* code_index_table = isolate->code_index_table();
320 ASSERT(code_index_table != NULL);
321 code_index_table->AddFunction(func);
322 // TODO(hausner): We need a way to remove these one-time execution
323 // functions from the global code description (PC mapping) tables so
324 // we don't pollute the system unnecessarily with stale data.
325 code_gen.FinalizePcDescriptors(code);
326 code_gen.FinalizeExceptionHandlers(code);
327
328 GrowableArray<const Object*> arguments; // no arguments.
329 const Array& kNoArgumentNames = Array::Handle();
330 result = DartEntry::InvokeStatic(func,
331 arguments,
332 kNoArgumentNames);
333 } else {
334 result = isolate->object_store()->sticky_error();
335 isolate->object_store()->clear_sticky_error();
336 }
337 isolate->set_long_jump_base(base);
338 return result.raw(); 285 return result.raw();
339 } 286 }
340 287
341 288
342 } // namespace dart 289 } // namespace dart
OLDNEW
« 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