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

Unified Diff: runtime/vm/dart_api_impl.cc

Issue 2572423004: Reapply "Save and restore feedback from JIT." (Closed)
Patch Set: Created 4 years 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
Index: runtime/vm/dart_api_impl.cc
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 61daa777f0707c8bb892261a75b4ce4fd34818c1..638a4bf8dfed2312441630f99494df03e05262c2 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -36,6 +36,7 @@
#include "vm/port.h"
#include "vm/precompiler.h"
#include "vm/profiler.h"
+#include "vm/program_visitor.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/service_event.h"
@@ -112,9 +113,9 @@ const char* CanonicalFunction(const char* func) {
// An object visitor which will iterate over all the function objects in the
// heap and check if the result type and parameter types are canonicalized
// or not. An assertion is raised if a type is not canonicalized.
-class FunctionVisitor : public ObjectVisitor {
+class CheckFunctionTypesVisitor : public ObjectVisitor {
public:
- explicit FunctionVisitor(Thread* thread)
+ explicit CheckFunctionTypesVisitor(Thread* thread)
: classHandle_(Class::Handle(thread->zone())),
funcHandle_(Function::Handle(thread->zone())),
typeHandle_(AbstractType::Handle(thread->zone())) {}
@@ -1572,7 +1573,7 @@ Dart_CreateSnapshot(uint8_t** vm_isolate_snapshot_buffer,
#if defined(DEBUG)
I->heap()->CollectAllGarbage();
- FunctionVisitor check_canonical(T);
+ CheckFunctionTypesVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
#endif // #if defined(DEBUG)
@@ -1611,7 +1612,7 @@ static Dart_Handle createLibrarySnapshot(Dart_Handle library,
#if defined(DEBUG)
I->heap()->CollectAllGarbage();
- FunctionVisitor check_canonical(T);
+ CheckFunctionTypesVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
#endif // #if defined(DEBUG)
@@ -6426,47 +6427,175 @@ DART_EXPORT void Dart_SetThreadName(const char* name) {
}
-// The precompiler is included in dart_bootstrap and dart_noopt, and
-// excluded from dart and dart_precompiled_runtime.
-#if !defined(DART_PRECOMPILER)
+DART_EXPORT
+Dart_Handle Dart_SaveJITFeedback(uint8_t** buffer, intptr_t* buffer_length) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return Api::NewError("No JIT feedback to save on an AOT runtime.");
+#elif defined(PRODUCT)
+ // TOOD(rmacnak): We'd need to include the JSON printing code again.
+ return Api::NewError("Dart_SaveJITFeedback not supported in PRODUCT mode.");
+#else
+ Thread* thread = Thread::Current();
+ DARTSCOPE(thread);
+ Isolate* isolate = thread->isolate();
+ Zone* zone = thread->zone();
-DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
-}
+ if (buffer == NULL) {
+ RETURN_NULL_ERROR(buffer);
+ }
+ if (buffer_length == NULL) {
+ RETURN_NULL_ERROR(buffer_length);
+ }
+ JSONStream js_stream;
+ {
+ JSONObject js_profile(&js_stream);
+ js_profile.AddProperty("vmVersion", Version::CommitString());
+ js_profile.AddProperty("asserts", FLAG_enable_asserts);
+ js_profile.AddProperty("typeChecks", FLAG_enable_type_checks);
+
+ {
+ JSONArray js_scripts(&js_profile, "scripts");
+
+ const GrowableObjectArray& libraries = GrowableObjectArray::Handle(
+ zone, isolate->object_store()->libraries());
+ Library& library = Library::Handle(zone);
+ Array& scripts = Array::Handle(zone);
+ Script& script = Script::Handle(zone);
+ String& uri = String::Handle(zone);
+ for (intptr_t i = 0; i < libraries.Length(); i++) {
+ library ^= libraries.At(i);
+ scripts = library.LoadedScripts();
+ for (intptr_t j = 0; j < scripts.Length(); j++) {
+ script ^= scripts.At(j);
+ JSONObject js_script(&js_scripts);
+ uri = script.url();
+ js_script.AddProperty("uri", uri.ToCString());
+ int64_t fp = script.SourceFingerprint();
+ js_script.AddProperty64("checksum", fp);
+ }
+ }
+ }
-DART_EXPORT Dart_Handle
-Dart_CreatePrecompiledSnapshotAssembly(uint8_t** assembly_buffer,
- intptr_t* assembly_size) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
- return 0;
-}
+ {
+ JSONArray js_classes(&js_profile, "classes");
+
+ ClassTable* classes = isolate->class_table();
+ Class& cls = Class::Handle(zone);
+ Library& library = Library::Handle(zone);
+ String& uri = String::Handle(zone);
+ String& name = String::Handle(zone);
+ for (intptr_t cid = kNumPredefinedCids; cid < classes->NumCids(); cid++) {
+ if (!classes->HasValidClassAt(cid)) continue;
+ cls ^= classes->At(cid);
+ library = cls.library();
+ JSONObject js_class(&js_classes);
+ js_class.AddProperty("cid", cid);
+ uri = library.url();
+ js_class.AddProperty("uri", uri.ToCString());
+ name = cls.Name();
+ name = String::RemovePrivateKey(name);
+ js_class.AddProperty("name", name.ToCString());
+ }
+ }
+ {
+ JSONArray js_functions(&js_profile, "functions");
+
+ class JITFeedbackFunctionVisitor : public FunctionVisitor {
+ public:
+ JITFeedbackFunctionVisitor(JSONArray* js_functions, Zone* zone)
+ : js_functions_(js_functions),
+ function_(Function::Handle(zone)),
+ owner_(Class::Handle(zone)),
+ name_(String::Handle(zone)),
+ ic_datas_(Array::Handle(zone)),
+ ic_data_(ICData::Handle(zone)),
+ entry_(Object::Handle(zone)) {}
+
+ void Visit(const Function& function) {
+ if (function.usage_counter() == 0) return;
+
+ JSONObject js_function(js_functions_);
+ name_ = function.name();
+ name_ = String::RemovePrivateKey(name_);
+ js_function.AddProperty("name", name_.ToCString());
+ owner_ ^= function.Owner();
+ js_function.AddProperty("class", owner_.id());
+ js_function.AddProperty("tokenPos", function.token_pos().value());
+ js_function.AddProperty("kind",
+ static_cast<intptr_t>(function.kind()));
+ intptr_t usage = function.usage_counter();
+ if (usage < 0) {
+ // Function was in the background compiler's queue.
+ usage = FLAG_optimization_counter_threshold;
+ }
+ js_function.AddProperty("usageCounter", usage);
+
+ ic_datas_ = function.ic_data_array();
+ JSONArray js_icdatas(&js_function, "ics");
+ if (ic_datas_.IsNull()) return;
+
+ for (intptr_t j = 0; j < ic_datas_.Length(); j++) {
+ entry_ = ic_datas_.At(j);
+ if (!entry_.IsICData()) continue; // Skip edge counters.
+ ic_data_ ^= entry_.raw();
+
+ JSONObject js_icdata(&js_icdatas);
+ js_icdata.AddProperty("deoptId", ic_data_.deopt_id());
+ name_ = ic_data_.target_name();
+ name_ = String::RemovePrivateKey(name_);
+ js_icdata.AddProperty("selector", name_.ToCString());
+ js_icdata.AddProperty("isStaticCall", ic_data_.is_static_call());
+ intptr_t num_args_checked = ic_data_.NumArgsTested();
+ js_icdata.AddProperty("argsTested", num_args_checked);
+ JSONArray js_entries(&js_icdata, "entries");
+ for (intptr_t check = 0; check < ic_data_.NumberOfChecks();
+ check++) {
+ GrowableArray<intptr_t> class_ids(num_args_checked);
+ ic_data_.GetClassIdsAt(check, &class_ids);
+ for (intptr_t k = 0; k < num_args_checked; k++) {
+ ASSERT(class_ids[k] != kIllegalCid);
+ js_entries.AddValue(class_ids[k]);
+ }
+ js_entries.AddValue(ic_data_.GetCountAt(check));
+ }
+ }
+ }
-DART_EXPORT Dart_Handle
-Dart_CreatePrecompiledSnapshotBlob(uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
- intptr_t* isolate_snapshot_size,
- uint8_t** instructions_blob_buffer,
- intptr_t* instructions_blob_size,
- uint8_t** rodata_blob_buffer,
- intptr_t* rodata_blob_size) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
+ private:
+ JSONArray* js_functions_;
+ Function& function_;
+ Class& owner_;
+ String& name_;
+ Array& ic_datas_;
+ ICData& ic_data_;
+ Object& entry_;
+ };
+
+ JITFeedbackFunctionVisitor visitor(&js_functions, zone);
+ ProgramVisitor::VisitFunctions(&visitor);
+ }
+ }
+
+ js_stream.Steal(reinterpret_cast<char**>(buffer), buffer_length);
+ return Api::Success();
+#endif
}
-#else // DART_PRECOMPILER
DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields) {
+Dart_Precompile(Dart_QualifiedFunctionName entry_points[],
+ bool reset_fields,
+ uint8_t* jit_feedback,
+ intptr_t jit_feedback_length) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_BEGIN_END;
DARTSCOPE(Thread::Current());
@@ -6478,8 +6607,8 @@ Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields) {
return result;
}
CHECK_CALLBACK_STATE(T);
- const Error& error =
- Error::Handle(Precompiler::CompileAll(entry_points, reset_fields));
+ const Error& error = Error::Handle(Precompiler::CompileAll(
+ entry_points, reset_fields, jit_feedback, jit_feedback_length));
if (!error.IsNull()) {
return Api::NewHandle(T, error.raw());
}
@@ -6492,9 +6621,12 @@ DART_EXPORT Dart_Handle
Dart_CreatePrecompiledSnapshotAssembly(uint8_t** assembly_buffer,
intptr_t* assembly_size) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_DURATION;
DARTSCOPE(Thread::Current());
@@ -6540,9 +6672,12 @@ Dart_CreatePrecompiledSnapshotBlob(uint8_t** vm_isolate_snapshot_buffer,
uint8_t** rodata_blob_buffer,
intptr_t* rodata_blob_size) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_DURATION;
DARTSCOPE(Thread::Current());
@@ -6596,7 +6731,6 @@ Dart_CreatePrecompiledSnapshotBlob(uint8_t** vm_isolate_snapshot_buffer,
return Api::Success();
#endif
}
-#endif // DART_PRECOMPILER
DART_EXPORT Dart_Handle Dart_PrecompileJIT() {

Powered by Google App Engine
This is Rietveld 408576698