| 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 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 ASSERT(!function.HasCode()); | 171 ASSERT(!function.HasCode()); |
| 172 const Error& error = Error::Handle(Compiler::CompileFunction(thread, | 172 const Error& error = Error::Handle(Compiler::CompileFunction(thread, |
| 173 function)); | 173 function)); |
| 174 if (!error.IsNull()) { | 174 if (!error.IsNull()) { |
| 175 Exceptions::PropagateError(error); | 175 Exceptions::PropagateError(error); |
| 176 } | 176 } |
| 177 } | 177 } |
| 178 | 178 |
| 179 | 179 |
| 180 RawError* Compiler::Compile(const Library& library, const Script& script) { | 180 RawError* Compiler::Compile(const Library& library, const Script& script) { |
| 181 Isolate* const isolate = Isolate::Current(); | |
| 182 StackZone zone(isolate); | |
| 183 LongJumpScope jump; | 181 LongJumpScope jump; |
| 184 if (setjmp(*jump.Set()) == 0) { | 182 if (setjmp(*jump.Set()) == 0) { |
| 183 Isolate* const isolate = Isolate::Current(); |
| 184 StackZone zone(isolate); |
| 185 if (FLAG_trace_compiler) { | 185 if (FLAG_trace_compiler) { |
| 186 const String& script_url = String::Handle(script.url()); | 186 const String& script_url = String::Handle(script.url()); |
| 187 // TODO(iposva): Extract script kind. | 187 // TODO(iposva): Extract script kind. |
| 188 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 188 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
| 189 } | 189 } |
| 190 const String& library_key = String::Handle(library.private_key()); | 190 const String& library_key = String::Handle(library.private_key()); |
| 191 script.Tokenize(library_key); | 191 script.Tokenize(library_key); |
| 192 Parser::ParseCompilationUnit(library, script); | 192 Parser::ParseCompilationUnit(library, script); |
| 193 return Error::null(); | 193 return Error::null(); |
| 194 } else { | 194 } else { |
| 195 Isolate* const isolate = Isolate::Current(); |
| 196 StackZone zone(isolate); |
| 195 Error& error = Error::Handle(); | 197 Error& error = Error::Handle(); |
| 196 error = isolate->object_store()->sticky_error(); | 198 error = isolate->object_store()->sticky_error(); |
| 197 isolate->object_store()->clear_sticky_error(); | 199 isolate->object_store()->clear_sticky_error(); |
| 198 return error.raw(); | 200 return error.raw(); |
| 199 } | 201 } |
| 200 UNREACHABLE(); | 202 UNREACHABLE(); |
| 201 return Error::null(); | 203 return Error::null(); |
| 202 } | 204 } |
| 203 | 205 |
| 204 | 206 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // also allows us to reset the marked_for_parsing state in case we see an | 286 // also allows us to reset the marked_for_parsing state in case we see an |
| 285 // error. | 287 // error. |
| 286 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); | 288 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); |
| 287 Class& parse_class = Class::Handle(isolate); | 289 Class& parse_class = Class::Handle(isolate); |
| 288 const GrowableObjectArray& parse_list = | 290 const GrowableObjectArray& parse_list = |
| 289 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); | 291 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); |
| 290 const GrowableObjectArray& patch_list = | 292 const GrowableObjectArray& patch_list = |
| 291 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); | 293 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); |
| 292 | 294 |
| 293 // Parse the class and all the interfaces it implements and super classes. | 295 // Parse the class and all the interfaces it implements and super classes. |
| 294 StackZone zone(isolate); | |
| 295 LongJumpScope jump; | 296 LongJumpScope jump; |
| 296 if (setjmp(*jump.Set()) == 0) { | 297 if (setjmp(*jump.Set()) == 0) { |
| 298 StackZone zone(isolate); |
| 297 if (FLAG_trace_compiler) { | 299 if (FLAG_trace_compiler) { |
| 298 ISL_Print("Compiling Class %s '%s'\n", "", cls.ToCString()); | 300 ISL_Print("Compiling Class %s '%s'\n", "", cls.ToCString()); |
| 299 } | 301 } |
| 300 | 302 |
| 301 // Add the primary class which needs to be parsed to the parse list. | 303 // Add the primary class which needs to be parsed to the parse list. |
| 302 // Mark the class as parsed so that we don't recursively add the same | 304 // Mark the class as parsed so that we don't recursively add the same |
| 303 // class back into the list. | 305 // class back into the list. |
| 304 parse_list.Add(cls); | 306 parse_list.Add(cls); |
| 305 cls.set_is_marked_for_parsing(); | 307 cls.set_is_marked_for_parsing(); |
| 306 | 308 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 if (parse_class.is_marked_for_parsing()) { | 347 if (parse_class.is_marked_for_parsing()) { |
| 346 parse_class.reset_is_marked_for_parsing(); | 348 parse_class.reset_is_marked_for_parsing(); |
| 347 } | 349 } |
| 348 } | 350 } |
| 349 for (intptr_t i = 0; i < patch_list.Length(); i++) { | 351 for (intptr_t i = 0; i < patch_list.Length(); i++) { |
| 350 parse_class ^= patch_list.At(i); | 352 parse_class ^= patch_list.At(i); |
| 351 if (parse_class.is_marked_for_parsing()) { | 353 if (parse_class.is_marked_for_parsing()) { |
| 352 parse_class.reset_is_marked_for_parsing(); | 354 parse_class.reset_is_marked_for_parsing(); |
| 353 } | 355 } |
| 354 } | 356 } |
| 355 | 357 Isolate* const isolate = Isolate::Current(); |
| 358 StackZone zone(isolate); |
| 356 Error& error = Error::Handle(isolate); | 359 Error& error = Error::Handle(isolate); |
| 357 error = isolate->object_store()->sticky_error(); | 360 error = isolate->object_store()->sticky_error(); |
| 358 isolate->object_store()->clear_sticky_error(); | 361 isolate->object_store()->clear_sticky_error(); |
| 359 return error.raw(); | 362 return error.raw(); |
| 360 } | 363 } |
| 361 UNREACHABLE(); | 364 UNREACHABLE(); |
| 362 return Error::null(); | 365 return Error::null(); |
| 363 } | 366 } |
| 364 | 367 |
| 365 | 368 |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 if (optimized && FLAG_trace_inlining_intervals) { | 960 if (optimized && FLAG_trace_inlining_intervals) { |
| 958 code.DumpInlinedIntervals(); | 961 code.DumpInlinedIntervals(); |
| 959 } | 962 } |
| 960 } | 963 } |
| 961 | 964 |
| 962 | 965 |
| 963 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, | 966 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| 964 const Function& function, | 967 const Function& function, |
| 965 bool optimized, | 968 bool optimized, |
| 966 intptr_t osr_id) { | 969 intptr_t osr_id) { |
| 967 Thread* const thread = Thread::Current(); | |
| 968 Isolate* const isolate = thread->isolate(); | |
| 969 StackZone stack_zone(isolate); | |
| 970 Zone* const zone = stack_zone.GetZone(); | |
| 971 LongJumpScope jump; | 970 LongJumpScope jump; |
| 972 if (setjmp(*jump.Set()) == 0) { | 971 if (setjmp(*jump.Set()) == 0) { |
| 972 Thread* const thread = Thread::Current(); |
| 973 Isolate* const isolate = thread->isolate(); |
| 974 StackZone stack_zone(isolate); |
| 975 Zone* const zone = stack_zone.GetZone(); |
| 973 TIMERSCOPE(isolate, time_compilation); | 976 TIMERSCOPE(isolate, time_compilation); |
| 974 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 977 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |
| 975 per_compile_timer.Start(); | 978 per_compile_timer.Start(); |
| 976 ParsedFunction* parsed_function = new(zone) ParsedFunction( | 979 ParsedFunction* parsed_function = new(zone) ParsedFunction( |
| 977 thread, Function::ZoneHandle(zone, function.raw())); | 980 thread, Function::ZoneHandle(zone, function.raw())); |
| 978 if (FLAG_trace_compiler) { | 981 if (FLAG_trace_compiler) { |
| 979 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 982 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
| 980 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 983 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
| 981 (optimized ? "optimized " : ""), | 984 (optimized ? "optimized " : ""), |
| 982 function.ToFullyQualifiedCString(), | 985 function.ToFullyQualifiedCString(), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 } else if (FLAG_disassemble_optimized && | 1028 } else if (FLAG_disassemble_optimized && |
| 1026 optimized && | 1029 optimized && |
| 1027 FlowGraphPrinter::ShouldPrint(function)) { | 1030 FlowGraphPrinter::ShouldPrint(function)) { |
| 1028 // TODO(fschneider): Print unoptimized code along with the optimized code. | 1031 // TODO(fschneider): Print unoptimized code along with the optimized code. |
| 1029 ISL_Print("*** BEGIN CODE\n"); | 1032 ISL_Print("*** BEGIN CODE\n"); |
| 1030 DisassembleCode(function, true); | 1033 DisassembleCode(function, true); |
| 1031 ISL_Print("*** END CODE\n"); | 1034 ISL_Print("*** END CODE\n"); |
| 1032 } | 1035 } |
| 1033 return Error::null(); | 1036 return Error::null(); |
| 1034 } else { | 1037 } else { |
| 1038 Thread* const thread = Thread::Current(); |
| 1039 Isolate* const isolate = thread->isolate(); |
| 1040 StackZone stack_zone(isolate); |
| 1035 Error& error = Error::Handle(); | 1041 Error& error = Error::Handle(); |
| 1036 // We got an error during compilation. | 1042 // We got an error during compilation. |
| 1037 error = isolate->object_store()->sticky_error(); | 1043 error = isolate->object_store()->sticky_error(); |
| 1038 isolate->object_store()->clear_sticky_error(); | 1044 isolate->object_store()->clear_sticky_error(); |
| 1039 return error.raw(); | 1045 return error.raw(); |
| 1040 } | 1046 } |
| 1041 UNREACHABLE(); | 1047 UNREACHABLE(); |
| 1042 return Error::null(); | 1048 return Error::null(); |
| 1043 } | 1049 } |
| 1044 | 1050 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1058 VMTagScope tagScope(thread->isolate(), VMTag::kCompileOptimizedTagId); | 1064 VMTagScope tagScope(thread->isolate(), VMTag::kCompileOptimizedTagId); |
| 1059 CompilationPipeline* pipeline = | 1065 CompilationPipeline* pipeline = |
| 1060 CompilationPipeline::New(thread->zone(), function); | 1066 CompilationPipeline::New(thread->zone(), function); |
| 1061 return CompileFunctionHelper(pipeline, function, true, osr_id); | 1067 return CompileFunctionHelper(pipeline, function, true, osr_id); |
| 1062 } | 1068 } |
| 1063 | 1069 |
| 1064 | 1070 |
| 1065 // This is only used from unit tests. | 1071 // This is only used from unit tests. |
| 1066 RawError* Compiler::CompileParsedFunction( | 1072 RawError* Compiler::CompileParsedFunction( |
| 1067 ParsedFunction* parsed_function) { | 1073 ParsedFunction* parsed_function) { |
| 1068 Isolate* const isolate = Isolate::Current(); | |
| 1069 LongJumpScope jump; | 1074 LongJumpScope jump; |
| 1070 if (setjmp(*jump.Set()) == 0) { | 1075 if (setjmp(*jump.Set()) == 0) { |
| 1071 // Non-optimized code generator. | 1076 // Non-optimized code generator. |
| 1072 DartCompilationPipeline pipeline; | 1077 DartCompilationPipeline pipeline; |
| 1073 CompileParsedFunctionHelper(&pipeline, | 1078 CompileParsedFunctionHelper(&pipeline, |
| 1074 parsed_function, | 1079 parsed_function, |
| 1075 false, | 1080 false, |
| 1076 Isolate::kNoDeoptId); | 1081 Isolate::kNoDeoptId); |
| 1077 if (FLAG_disassemble) { | 1082 if (FLAG_disassemble) { |
| 1078 DisassembleCode(parsed_function->function(), false); | 1083 DisassembleCode(parsed_function->function(), false); |
| 1079 } | 1084 } |
| 1080 return Error::null(); | 1085 return Error::null(); |
| 1081 } else { | 1086 } else { |
| 1087 Isolate* const isolate = Isolate::Current(); |
| 1082 Error& error = Error::Handle(); | 1088 Error& error = Error::Handle(); |
| 1083 // We got an error during compilation. | 1089 // We got an error during compilation. |
| 1084 error = isolate->object_store()->sticky_error(); | 1090 error = isolate->object_store()->sticky_error(); |
| 1085 isolate->object_store()->clear_sticky_error(); | 1091 isolate->object_store()->clear_sticky_error(); |
| 1086 return error.raw(); | 1092 return error.raw(); |
| 1087 } | 1093 } |
| 1088 UNREACHABLE(); | 1094 UNREACHABLE(); |
| 1089 return Error::null(); | 1095 return Error::null(); |
| 1090 } | 1096 } |
| 1091 | 1097 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 } | 1141 } |
| 1136 return error.raw(); | 1142 return error.raw(); |
| 1137 } | 1143 } |
| 1138 | 1144 |
| 1139 | 1145 |
| 1140 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { | 1146 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| 1141 ASSERT(field.is_static()); | 1147 ASSERT(field.is_static()); |
| 1142 // The VM sets the field's value to transiton_sentinel prior to | 1148 // The VM sets the field's value to transiton_sentinel prior to |
| 1143 // evaluating the initializer value. | 1149 // evaluating the initializer value. |
| 1144 ASSERT(field.value() == Object::transition_sentinel().raw()); | 1150 ASSERT(field.value() == Object::transition_sentinel().raw()); |
| 1145 Isolate* const isolate = Isolate::Current(); | |
| 1146 StackZone zone(isolate); | |
| 1147 LongJumpScope jump; | 1151 LongJumpScope jump; |
| 1148 if (setjmp(*jump.Set()) == 0) { | 1152 if (setjmp(*jump.Set()) == 0) { |
| 1153 Isolate* const isolate = Isolate::Current(); |
| 1154 StackZone zone(isolate); |
| 1149 ParsedFunction* parsed_function = | 1155 ParsedFunction* parsed_function = |
| 1150 Parser::ParseStaticFieldInitializer(field); | 1156 Parser::ParseStaticFieldInitializer(field); |
| 1151 | 1157 |
| 1152 parsed_function->AllocateVariables(); | 1158 parsed_function->AllocateVariables(); |
| 1153 // Non-optimized code generator. | 1159 // Non-optimized code generator. |
| 1154 DartCompilationPipeline pipeline; | 1160 DartCompilationPipeline pipeline; |
| 1155 CompileParsedFunctionHelper(&pipeline, | 1161 CompileParsedFunctionHelper(&pipeline, |
| 1156 parsed_function, | 1162 parsed_function, |
| 1157 false, | 1163 false, |
| 1158 Isolate::kNoDeoptId); | 1164 Isolate::kNoDeoptId); |
| 1159 | 1165 |
| 1160 // Invoke the function to evaluate the expression. | 1166 // Invoke the function to evaluate the expression. |
| 1161 const Function& initializer = parsed_function->function(); | 1167 const Function& initializer = parsed_function->function(); |
| 1162 const Object& result = PassiveObject::Handle( | 1168 const Object& result = PassiveObject::Handle( |
| 1163 DartEntry::InvokeFunction(initializer, Object::empty_array())); | 1169 DartEntry::InvokeFunction(initializer, Object::empty_array())); |
| 1164 return result.raw(); | 1170 return result.raw(); |
| 1165 } else { | 1171 } else { |
| 1172 Isolate* const isolate = Isolate::Current(); |
| 1173 StackZone zone(isolate); |
| 1166 const Error& error = | 1174 const Error& error = |
| 1167 Error::Handle(isolate, isolate->object_store()->sticky_error()); | 1175 Error::Handle(isolate, isolate->object_store()->sticky_error()); |
| 1168 isolate->object_store()->clear_sticky_error(); | 1176 isolate->object_store()->clear_sticky_error(); |
| 1169 return error.raw(); | 1177 return error.raw(); |
| 1170 } | 1178 } |
| 1171 UNREACHABLE(); | 1179 UNREACHABLE(); |
| 1172 return Object::null(); | 1180 return Object::null(); |
| 1173 } | 1181 } |
| 1174 | 1182 |
| 1175 | 1183 |
| 1176 | 1184 |
| 1177 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 1185 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 1178 Thread* const thread = Thread::Current(); | |
| 1179 Isolate* const isolate = thread->isolate(); | |
| 1180 LongJumpScope jump; | 1186 LongJumpScope jump; |
| 1181 if (setjmp(*jump.Set()) == 0) { | 1187 if (setjmp(*jump.Set()) == 0) { |
| 1188 Thread* const thread = Thread::Current(); |
| 1182 if (FLAG_trace_compiler) { | 1189 if (FLAG_trace_compiler) { |
| 1183 ISL_Print("compiling expression: "); | 1190 ISL_Print("compiling expression: "); |
| 1184 AstPrinter::PrintNode(fragment); | 1191 AstPrinter::PrintNode(fragment); |
| 1185 } | 1192 } |
| 1186 | 1193 |
| 1187 // Create a dummy function object for the code generator. | 1194 // Create a dummy function object for the code generator. |
| 1188 // The function needs to be associated with a named Class: the interface | 1195 // The function needs to be associated with a named Class: the interface |
| 1189 // Function fits the bill. | 1196 // Function fits the bill. |
| 1190 const char* kEvalConst = "eval_const"; | 1197 const char* kEvalConst = "eval_const"; |
| 1191 const Function& func = Function::ZoneHandle(Function::New( | 1198 const Function& func = Function::ZoneHandle(Function::New( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1221 DartCompilationPipeline pipeline; | 1228 DartCompilationPipeline pipeline; |
| 1222 CompileParsedFunctionHelper(&pipeline, | 1229 CompileParsedFunctionHelper(&pipeline, |
| 1223 parsed_function, | 1230 parsed_function, |
| 1224 false, | 1231 false, |
| 1225 Isolate::kNoDeoptId); | 1232 Isolate::kNoDeoptId); |
| 1226 | 1233 |
| 1227 const Object& result = PassiveObject::Handle( | 1234 const Object& result = PassiveObject::Handle( |
| 1228 DartEntry::InvokeFunction(func, Object::empty_array())); | 1235 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 1229 return result.raw(); | 1236 return result.raw(); |
| 1230 } else { | 1237 } else { |
| 1238 Thread* const thread = Thread::Current(); |
| 1239 Isolate* const isolate = thread->isolate(); |
| 1231 const Object& result = | 1240 const Object& result = |
| 1232 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1241 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1233 isolate->object_store()->clear_sticky_error(); | 1242 isolate->object_store()->clear_sticky_error(); |
| 1234 return result.raw(); | 1243 return result.raw(); |
| 1235 } | 1244 } |
| 1236 UNREACHABLE(); | 1245 UNREACHABLE(); |
| 1237 return Object::null(); | 1246 return Object::null(); |
| 1238 } | 1247 } |
| 1239 | 1248 |
| 1240 } // namespace dart | 1249 } // namespace dart |
| OLD | NEW |