| Index: runtime/vm/dart_api_impl.cc
|
| diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
|
| index 2bec82533531ee0781624ea9868de20ec54dcead..27ad7ae5c18d5973ffa2dce77808b4c099ece66f 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() {
|
|
|