| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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/compilation_trace.h" | 5 #include "vm/compilation_trace.h" |
| 6 | 6 |
| 7 #include "vm/longjump.h" | 7 #include "vm/longjump.h" |
| 8 #include "vm/object_store.h" | 8 #include "vm/object_store.h" |
| 9 #include "vm/resolver.h" | 9 #include "vm/resolver.h" |
| 10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 CompilationTraceSaver::CompilationTraceSaver(Zone* zone) | 14 CompilationTraceSaver::CompilationTraceSaver(Zone* zone) |
| 15 : buf_(zone, 4 * KB), | 15 : buf_(zone, 4 * KB), |
| 16 func_name_(String::Handle(zone)), | 16 func_name_(String::Handle(zone)), |
| 17 cls_(Class::Handle(zone)), | 17 cls_(Class::Handle(zone)), |
| 18 cls_name_(String::Handle(zone)), | 18 cls_name_(String::Handle(zone)), |
| 19 lib_(Library::Handle(zone)), | 19 lib_(Library::Handle(zone)), |
| 20 uri_(String::Handle(zone)) {} | 20 uri_(String::Handle(zone)) {} |
| 21 | 21 |
| 22 | |
| 23 void CompilationTraceSaver::Visit(const Function& function) { | 22 void CompilationTraceSaver::Visit(const Function& function) { |
| 24 if (!function.HasCode()) { | 23 if (!function.HasCode()) { |
| 25 return; // Not compiled. | 24 return; // Not compiled. |
| 26 } | 25 } |
| 27 if (function.parent_function() != Function::null()) { | 26 if (function.parent_function() != Function::null()) { |
| 28 // Lookup works poorly for local functions. We compile all local functions | 27 // Lookup works poorly for local functions. We compile all local functions |
| 29 // in a compiled function instead. | 28 // in a compiled function instead. |
| 30 return; | 29 return; |
| 31 } | 30 } |
| 32 | 31 |
| 33 func_name_ = function.name(); | 32 func_name_ = function.name(); |
| 34 func_name_ = String::RemovePrivateKey(func_name_); | 33 func_name_ = String::RemovePrivateKey(func_name_); |
| 35 cls_ = function.Owner(); | 34 cls_ = function.Owner(); |
| 36 cls_name_ = cls_.Name(); | 35 cls_name_ = cls_.Name(); |
| 37 cls_name_ = String::RemovePrivateKey(cls_name_); | 36 cls_name_ = String::RemovePrivateKey(cls_name_); |
| 38 lib_ = cls_.library(); | 37 lib_ = cls_.library(); |
| 39 uri_ = lib_.url(); | 38 uri_ = lib_.url(); |
| 40 buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(), | 39 buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(), |
| 41 func_name_.ToCString()); | 40 func_name_.ToCString()); |
| 42 } | 41 } |
| 43 | 42 |
| 44 | |
| 45 CompilationTraceLoader::CompilationTraceLoader(Thread* thread) | 43 CompilationTraceLoader::CompilationTraceLoader(Thread* thread) |
| 46 : thread_(thread), | 44 : thread_(thread), |
| 47 zone_(thread->zone()), | 45 zone_(thread->zone()), |
| 48 uri_(String::Handle(zone_)), | 46 uri_(String::Handle(zone_)), |
| 49 class_name_(String::Handle(zone_)), | 47 class_name_(String::Handle(zone_)), |
| 50 function_name_(String::Handle(zone_)), | 48 function_name_(String::Handle(zone_)), |
| 51 function_name2_(String::Handle(zone_)), | 49 function_name2_(String::Handle(zone_)), |
| 52 lib_(Library::Handle(zone_)), | 50 lib_(Library::Handle(zone_)), |
| 53 cls_(Class::Handle(zone_)), | 51 cls_(Class::Handle(zone_)), |
| 54 function_(Function::Handle(zone_)), | 52 function_(Function::Handle(zone_)), |
| 55 function2_(Function::Handle(zone_)), | 53 function2_(Function::Handle(zone_)), |
| 56 field_(Field::Handle(zone_)), | 54 field_(Field::Handle(zone_)), |
| 57 error_(Object::Handle(zone_)) {} | 55 error_(Object::Handle(zone_)) {} |
| 58 | 56 |
| 59 | |
| 60 static char* FindCharacter(char* str, char goal, char* limit) { | 57 static char* FindCharacter(char* str, char goal, char* limit) { |
| 61 while (str < limit) { | 58 while (str < limit) { |
| 62 if (*str == goal) { | 59 if (*str == goal) { |
| 63 return str; | 60 return str; |
| 64 } | 61 } |
| 65 str++; | 62 str++; |
| 66 } | 63 } |
| 67 return NULL; | 64 return NULL; |
| 68 } | 65 } |
| 69 | 66 |
| 70 | |
| 71 RawObject* CompilationTraceLoader::CompileTrace(uint8_t* buffer, | 67 RawObject* CompilationTraceLoader::CompileTrace(uint8_t* buffer, |
| 72 intptr_t size) { | 68 intptr_t size) { |
| 73 // First compile functions named in the trace. | 69 // First compile functions named in the trace. |
| 74 char* cursor = reinterpret_cast<char*>(buffer); | 70 char* cursor = reinterpret_cast<char*>(buffer); |
| 75 char* limit = cursor + size; | 71 char* limit = cursor + size; |
| 76 while (cursor < limit) { | 72 while (cursor < limit) { |
| 77 char* uri = cursor; | 73 char* uri = cursor; |
| 78 char* comma1 = FindCharacter(uri, ',', limit); | 74 char* comma1 = FindCharacter(uri, ',', limit); |
| 79 if (comma1 == NULL) { | 75 if (comma1 == NULL) { |
| 80 break; | 76 break; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 error_ = CompileFunction(function_); | 125 error_ = CompileFunction(function_); |
| 130 if (error_.IsError()) { | 126 if (error_.IsError()) { |
| 131 return error_.raw(); | 127 return error_.raw(); |
| 132 } | 128 } |
| 133 } | 129 } |
| 134 } | 130 } |
| 135 | 131 |
| 136 return Object::null(); | 132 return Object::null(); |
| 137 } | 133 } |
| 138 | 134 |
| 139 | |
| 140 // Use a fuzzy match to find the right function to compile. This allows a | 135 // Use a fuzzy match to find the right function to compile. This allows a |
| 141 // compilation trace to remain mostly valid in the face of program changes, and | 136 // compilation trace to remain mostly valid in the face of program changes, and |
| 142 // deals with implicit/dispatcher functions that don't have proper names. | 137 // deals with implicit/dispatcher functions that don't have proper names. |
| 143 // - Ignore private name mangling | 138 // - Ignore private name mangling |
| 144 // - If looking for a getter and we only have the corresponding regular method, | 139 // - If looking for a getter and we only have the corresponding regular method, |
| 145 // compile the regular method, create its implicit closure and compile that. | 140 // compile the regular method, create its implicit closure and compile that. |
| 146 // - If looking for a regular method and we only have the corresponding getter, | 141 // - If looking for a regular method and we only have the corresponding getter, |
| 147 // compile the getter, create its method extractor and compile that. | 142 // compile the getter, create its method extractor and compile that. |
| 148 // - If looking for a getter and we only have a const field, evaluate the const | 143 // - If looking for a getter and we only have a const field, evaluate the const |
| 149 // field. | 144 // field. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 error_ = CompileFunction(function_); | 226 error_ = CompileFunction(function_); |
| 232 if (error_.IsError()) { | 227 if (error_.IsError()) { |
| 233 return error_.raw(); | 228 return error_.raw(); |
| 234 } | 229 } |
| 235 } | 230 } |
| 236 } | 231 } |
| 237 | 232 |
| 238 return Object::null(); | 233 return Object::null(); |
| 239 } | 234 } |
| 240 | 235 |
| 241 | |
| 242 RawObject* CompilationTraceLoader::CompileFunction(const Function& function) { | 236 RawObject* CompilationTraceLoader::CompileFunction(const Function& function) { |
| 243 if (function.is_abstract()) { | 237 if (function.is_abstract()) { |
| 244 return Object::null(); | 238 return Object::null(); |
| 245 } | 239 } |
| 246 return Compiler::CompileFunction(thread_, function); | 240 return Compiler::CompileFunction(thread_, function); |
| 247 } | 241 } |
| 248 | 242 |
| 249 | |
| 250 RawObject* CompilationTraceLoader::EvaluateInitializer(const Field& field) { | 243 RawObject* CompilationTraceLoader::EvaluateInitializer(const Field& field) { |
| 251 LongJumpScope jump; | 244 LongJumpScope jump; |
| 252 if (setjmp(*jump.Set()) == 0) { | 245 if (setjmp(*jump.Set()) == 0) { |
| 253 field_.EvaluateInitializer(); | 246 field_.EvaluateInitializer(); |
| 254 } else { | 247 } else { |
| 255 Thread* thread = Thread::Current(); | 248 Thread* thread = Thread::Current(); |
| 256 const Error& error = Error::Handle(thread->sticky_error()); | 249 const Error& error = Error::Handle(thread->sticky_error()); |
| 257 thread->clear_sticky_error(); | 250 thread->clear_sticky_error(); |
| 258 return error.raw(); | 251 return error.raw(); |
| 259 } | 252 } |
| 260 return Object::null(); | 253 return Object::null(); |
| 261 } | 254 } |
| 262 | 255 |
| 263 } // namespace dart | 256 } // namespace dart |
| OLD | NEW |