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

Unified Diff: runtime/vm/compilation_trace.cc

Issue 2922913004: Add Dart_Save/LoadCompilationTrace. (Closed)
Patch Set: . Created 3 years, 6 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/compilation_trace.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/compilation_trace.cc
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f972dfa1f9d86aadd048a4543f7b1a5ac302014c
--- /dev/null
+++ b/runtime/vm/compilation_trace.cc
@@ -0,0 +1,228 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compilation_trace.h"
+
+#include "vm/longjump.h"
+#include "vm/object_store.h"
+#include "vm/resolver.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+CompilationTraceSaver::CompilationTraceSaver(Zone* zone)
+ : buf_(zone, 4 * KB),
+ func_name_(String::Handle(zone)),
+ cls_(Class::Handle(zone)),
+ cls_name_(String::Handle(zone)),
+ lib_(Library::Handle(zone)),
+ uri_(String::Handle(zone)) {}
+
+
+void CompilationTraceSaver::Visit(const Function& function) {
+ if (!function.HasCode()) {
+ return;
+ }
+
+ func_name_ = function.name();
+ func_name_ = String::RemovePrivateKey(func_name_);
+ cls_ = function.Owner();
+ cls_name_ = cls_.Name();
+ cls_name_ = String::RemovePrivateKey(cls_name_);
+ lib_ = cls_.library();
+ uri_ = lib_.url();
+ buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(),
+ func_name_.ToCString());
+}
+
+
+CompilationTraceLoader::CompilationTraceLoader(Thread* thread)
+ : thread_(thread),
+ zone_(thread->zone()),
+ uri_(String::Handle(zone_)),
+ class_name_(String::Handle(zone_)),
+ function_name_(String::Handle(zone_)),
+ function_name2_(String::Handle(zone_)),
+ lib_(Library::Handle(zone_)),
+ cls_(Class::Handle(zone_)),
+ function_(Function::Handle(zone_)),
+ function2_(Function::Handle(zone_)),
+ field_(Field::Handle(zone_)),
+ error_(Object::Handle(zone_)) {}
+
+
+RawObject* CompilationTraceLoader::CompileTrace(char* buffer) {
+ // First compile functions named in the trace.
+ char* cursor = buffer;
+ while (cursor != NULL) {
+ char* uri = cursor;
+ char* comma1 = strchr(uri, ',');
+ if (comma1 == NULL) break;
+ *comma1 = 0;
+ char* cls_name = comma1 + 1;
+ char* comma2 = strchr(cls_name, ',');
+ if (comma2 == NULL) break;
+ *comma2 = 0;
+ char* func_name = comma2 + 1;
+ char* newline = strchr(func_name, '\n');
+ if (newline == NULL) break;
+ *newline = 0;
+ error_ = CompileTriple(uri, cls_name, func_name);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ cursor = newline + 1;
+ }
+
+ // Next, compile common dispatchers. These aren't found with the normal
+ // lookup above because they have irregular lookup that depends on the
+ // arguments descriptor (e.g. call() versus call(x)).
+ const Class& closure_class =
+ Class::Handle(zone_, thread_->isolate()->object_store()->closure_class());
+ Array& arguments_descriptor = Array::Handle(zone_);
+ Function& dispatcher = Function::Handle(zone_);
+ for (intptr_t argc = 1; argc <= 4; argc++) {
+ const intptr_t kTypeArgsLen = 0;
+ arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc);
+ dispatcher = closure_class.GetInvocationDispatcher(
+ Symbols::Call(), arguments_descriptor,
+ RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
+ error_ = CompileFunction(dispatcher);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ }
+
+ // Finally, compile closures in all compiled functions.
+ const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle(
+ zone_, thread_->isolate()->object_store()->closure_functions());
+ for (intptr_t i = 0; i < closure_functions.Length(); i++) {
+ function_ ^= closure_functions.At(i);
+ function2_ = function_.parent_function();
+ if (function2_.HasCode()) {
+ error_ = CompileFunction(function_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ }
+ }
+
+ return Object::null();
+}
+
+
+RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr,
+ const char* cls_cstr,
+ const char* func_cstr) {
+ uri_ = Symbols::New(thread_, uri_cstr);
+ class_name_ = Symbols::New(thread_, cls_cstr);
+ function_name_ = Symbols::New(thread_, func_cstr);
+
+ if (function_name_.Equals("_getMainClosure")) {
+ // The scheme for invoking main relies on compiling _getMainClosure after
+ // synthetically importing the root library.
+ return Object::null();
+ }
+
+ lib_ = Library::LookupLibrary(thread_, uri_);
+ if (lib_.IsNull()) {
+ // Missing library.
+ return Object::null();
+ }
+
+ bool is_getter = Field::IsGetterName(function_name_);
+ bool add_closure = false;
+
+ if (class_name_.Equals(Symbols::TopLevel())) {
+ function_ = lib_.LookupFunctionAllowPrivate(function_name_);
+ field_ = lib_.LookupFieldAllowPrivate(function_name_);
+ if (function_.IsNull() && is_getter) {
+ // Maybe this was a tear off.
+ add_closure = true;
+ function_name2_ = Field::NameFromGetter(function_name_);
+ function_ = lib_.LookupFunctionAllowPrivate(function_name2_);
+ field_ = lib_.LookupFieldAllowPrivate(function_name2_);
+ }
+ } else {
+ cls_ = lib_.SlowLookupClassAllowMultiPartPrivate(class_name_);
+ if (cls_.IsNull()) {
+ // Missing class.
+ return Object::null();
+ }
+
+ error_ = cls_.EnsureIsFinalized(thread_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+
+ function_ = cls_.LookupFunctionAllowPrivate(function_name_);
+ field_ = cls_.LookupFieldAllowPrivate(function_name_);
+ if (field_.IsNull() && is_getter) {
+ // Maybe this is a tear off.
+ add_closure = true;
+ function_name2_ = Field::NameFromGetter(function_name_);
+ function_ = cls_.LookupFunctionAllowPrivate(function_name2_);
+ field_ = cls_.LookupFieldAllowPrivate(function_name2_);
+ if (!function_.IsNull() && !function_.is_static()) {
+ // Maybe this was a method extractor.
+ function2_ =
+ Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_);
+ if (!function2_.IsNull()) {
+ error_ = CompileFunction(function2_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ }
+ }
+ }
+ }
+
+ if (!field_.IsNull() && field_.is_const() && field_.is_static() &&
+ (field_.StaticValue() == Object::sentinel().raw())) {
+ error_ = EvaluateInitializer(field_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ }
+
+ if (!function_.IsNull()) {
+ error_ = CompileFunction(function_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ if (add_closure) {
+ function_ = function_.ImplicitClosureFunction();
+ error_ = CompileFunction(function_);
+ if (error_.IsError()) {
+ return error_.raw();
+ }
+ }
+ }
+
+ return Object::null();
+}
+
+
+RawObject* CompilationTraceLoader::CompileFunction(const Function& function) {
+ if (function.is_abstract()) {
+ return Object::null();
+ }
+ return Compiler::CompileFunction(thread_, function);
+}
+
+
+RawObject* CompilationTraceLoader::EvaluateInitializer(const Field& field) {
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ field_.EvaluateInitializer();
+ } else {
+ Thread* thread = Thread::Current();
+ const Error& error = Error::Handle(thread->sticky_error());
+ thread->clear_sticky_error();
+ return error.raw();
+ }
+ return Object::null();
+}
+
+} // namespace dart
« no previous file with comments | « runtime/vm/compilation_trace.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698