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

Unified Diff: runtime/vm/object.cc

Issue 100103011: Changes to support dprof and Observatory profiler UIs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 12 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/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 83dcfc0e454e6977881b1aec3297d9738815cd7a..37fa9c353ac608ca9dacb7b22a9ebc3d42ec1ab6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1818,14 +1818,10 @@ intptr_t Class::FindFunctionIndex(const Function& needle) const {
funcs ^= functions();
ASSERT(!funcs.IsNull());
Function& function = reused_handles.FunctionHandle();
- String& function_name = reused_handles.StringHandle();
- String& needle_name = String::Handle(isolate);
- needle_name ^= needle.name();
const intptr_t len = funcs.Length();
for (intptr_t i = 0; i < len; i++) {
function ^= funcs.At(i);
- function_name ^= function.name();
- if (function_name.Equals(needle_name)) {
+ if (function.raw() == needle.raw()) {
return i;
}
}
@@ -1834,6 +1830,106 @@ intptr_t Class::FindFunctionIndex(const Function& needle) const {
}
+RawFunction* Class::FunctionFromIndex(intptr_t idx) const {
+ const Array& funcs = Array::Handle(functions());
+ if ((idx < 0) || (idx >= funcs.Length())) {
+ return Function::null();
+ }
+ Function& func = Function::Handle();
+ func ^= funcs.At(idx);
+ ASSERT(!func.IsNull());
+ return func.raw();
+}
+
+
+RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const {
+ const Array& funcs = Array::Handle(functions());
+ if ((idx < 0) || (idx >= funcs.Length())) {
+ return Function::null();
+ }
+ Function& func = Function::Handle();
+ func ^= funcs.At(idx);
+ ASSERT(!func.IsNull());
+ if (!func.HasImplicitClosureFunction()) {
+ return Function::null();
+ }
+ const Function& closure_func =
+ Function::Handle(func.ImplicitClosureFunction());
+ ASSERT(!closure_func.IsNull());
+ return closure_func.raw();
+}
+
+
+intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const {
+ Isolate* isolate = Isolate::Current();
+ if (EnsureIsFinalized(isolate) != Error::null()) {
+ return -1;
+ }
+ ReusableHandleScope reused_handles(isolate);
+ Array& funcs = reused_handles.ArrayHandle();
+ funcs ^= functions();
+ ASSERT(!funcs.IsNull());
+ Function& function = reused_handles.FunctionHandle();
+ Function& implicit_closure = Function::Handle();
+ const intptr_t len = funcs.Length();
+ for (intptr_t i = 0; i < len; i++) {
+ function ^= funcs.At(i);
+ implicit_closure ^= function.implicit_closure_function();
+ if (implicit_closure.IsNull()) {
+ // Skip non-implicit closure functions.
+ continue;
+ }
+ if (needle.raw() == implicit_closure.raw()) {
+ return i;
+ }
+ }
+ // No function found.
+ return -1;
+}
+
+
+
+intptr_t Class::FindInvocationDispatcherFunctionIndex(
+ const Function& needle) const {
+ Isolate* isolate = Isolate::Current();
+ if (EnsureIsFinalized(isolate) != Error::null()) {
+ return -1;
+ }
+ ReusableHandleScope reused_handles(isolate);
+ Array& funcs = reused_handles.ArrayHandle();
+ funcs ^= invocation_dispatcher_cache();
+ ASSERT(!funcs.IsNull());
+ Object& object = reused_handles.ObjectHandle();
+ const intptr_t len = funcs.Length();
+ for (intptr_t i = 0; i < len; i++) {
+ object = funcs.At(i);
+ // The invocation_dispatcher_cache is a table with some entries that
+ // are functions.
+ if (object.IsFunction()) {
+ if (Function::Cast(object).raw() == needle.raw()) {
+ return i;
+ }
+ }
+ }
+ // No function found.
+ return -1;
+}
+
+
+
+RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
+ ReusableHandleScope reused_handles(Isolate::Current());
+ Array& dispatcher_cache = reused_handles.ArrayHandle();
+ dispatcher_cache ^= invocation_dispatcher_cache();
+ Object& object = reused_handles.ObjectHandle();
+ object = dispatcher_cache.At(idx);
+ if (!object.IsFunction()) {
+ return Function::null();
+ }
+ return Function::Cast(object).raw();
+}
+
+
void Class::AddClosureFunction(const Function& function) const {
GrowableObjectArray& closures =
GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
@@ -1874,7 +1970,7 @@ RawFunction* Class::LookupClosureFunction(intptr_t token_pos) const {
return closure.raw();
}
-intptr_t Class::FindClosureIndex(intptr_t token_pos) const {
+intptr_t Class::FindClosureIndex(const Function& needle) const {
if (closures() == GrowableObjectArray::null()) {
return -1;
}
@@ -1884,19 +1980,27 @@ intptr_t Class::FindClosureIndex(intptr_t token_pos) const {
GrowableObjectArray::Handle(isolate, closures());
Function& closure = reused_handles.FunctionHandle();
intptr_t num_closures = closures_array.Length();
- intptr_t best_fit_token_pos = -1;
- intptr_t best_fit_index = -1;
for (intptr_t i = 0; i < num_closures; i++) {
closure ^= closures_array.At(i);
ASSERT(!closure.IsNull());
- if ((closure.token_pos() <= token_pos) &&
- (token_pos <= closure.end_token_pos()) &&
- (best_fit_token_pos < closure.token_pos())) {
- best_fit_index = i;
- best_fit_token_pos = closure.token_pos();
+ if (closure.raw() == needle.raw()) {
+ return i;
}
}
- return best_fit_index;
+ return -1;
+}
+
+
+RawFunction* Class::ClosureFunctionFromIndex(intptr_t idx) const {
+ const GrowableObjectArray& closures_array =
+ GrowableObjectArray::Handle(closures());
+ if ((idx < 0) || (idx >= closures_array.Length())) {
+ return Function::null();
+ }
+ Function& func = Function::Handle();
+ func ^= closures_array.At(idx);
+ ASSERT(!func.IsNull());
+ return func.raw();
}
@@ -2477,6 +2581,18 @@ intptr_t Class::FindFieldIndex(const Field& needle) const {
}
+RawField* Class::FieldFromIndex(intptr_t idx) const {
+ const Array& flds = Array::Handle(fields());
+ if ((idx < 0) || (idx >= flds.Length())) {
+ return Field::null();
+ }
+ Field& field = Field::Handle();
+ field ^= flds.At(idx);
+ ASSERT(!field.IsNull());
+ return field.raw();
+}
+
+
template <class FakeInstance>
RawClass* Class::New(intptr_t index) {
ASSERT(Object::class_class() != Class::null());
@@ -4451,6 +4567,54 @@ RawType* Function::RedirectionType() const {
}
+const char* Function::KindToCString(RawFunction::Kind kind) {
+ switch (kind) {
+ case RawFunction::kRegularFunction:
+ return "kRegularFunction";
+ break;
+ case RawFunction::kClosureFunction:
+ return "kClosureFunction";
+ break;
+ case RawFunction::kSignatureFunction:
+ return "kSignatureFunction";
+ break;
+ case RawFunction::kGetterFunction:
+ return "kGetterFunction";
+ break;
+ case RawFunction::kSetterFunction:
+ return "kSetterFunction";
+ break;
+ case RawFunction::kConstructor:
+ return "kConstructor";
+ break;
+ case RawFunction::kImplicitGetter:
+ return "kImplicitGetter";
+ break;
+ case RawFunction::kImplicitSetter:
+ return "kImplicitSetter";
+ break;
+ case RawFunction::kImplicitStaticFinalGetter:
+ return "kImplicitStaticFinalGetter";
+ break;
+ case RawFunction::kStaticInitializer:
+ return "kStaticInitializer";
+ break;
+ case RawFunction::kMethodExtractor:
+ return "kMethodExtractor";
+ break;
+ case RawFunction::kNoSuchMethodDispatcher:
+ return "kNoSuchMethodDispatcher";
+ break;
+ case RawFunction::kInvokeFieldDispatcher:
+ return "kInvokeFieldDispatcher";
+ break;
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
void Function::SetRedirectionType(const Type& type) const {
ASSERT(IsFactory());
Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5711,25 +5875,30 @@ void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
const char* function_name =
String::Handle(QualifiedUserVisibleName()).ToCString();
Class& cls = Class::Handle(Owner());
+ ASSERT(!cls.IsNull());
Error& err = Error::Handle();
err ^= cls.EnsureIsFinalized(Isolate::Current());
ASSERT(err.IsNull());
- const Function& func = *this;
- intptr_t id;
+ intptr_t id = -1;
+ const char* selector = NULL;
if (IsNonImplicitClosureFunction()) {
- id = cls.FindClosureIndex(token_pos());
+ id = cls.FindClosureIndex(*this);
+ selector = "closures";
+ } else if (IsImplicitClosureFunction()) {
+ id = cls.FindImplicitClosureFunctionIndex(*this);
+ selector = "implicit_closures";
+ } else if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
+ id = cls.FindInvocationDispatcherFunctionIndex(*this);
+ selector = "dispatchers";
} else {
- id = cls.FindFunctionIndex(func);
+ id = cls.FindFunctionIndex(*this);
+ selector = "functions";
}
ASSERT(id >= 0);
intptr_t cid = cls.id();
JSONObject jsobj(stream);
jsobj.AddProperty("type", JSONType(ref));
- if (IsNonImplicitClosureFunction()) {
- jsobj.AddPropertyF("id", "classes/%" Pd "/closures/%" Pd "", cid, id);
- } else {
- jsobj.AddPropertyF("id", "classes/%" Pd "/functions/%" Pd "", cid, id);
- }
+ jsobj.AddPropertyF("id", "classes/%" Pd "/%s/%" Pd "", cid, selector, id);
jsobj.AddProperty("name", internal_function_name);
jsobj.AddProperty("user_name", function_name);
if (ref) return;
@@ -5737,44 +5906,7 @@ void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
jsobj.AddProperty("is_const", is_const());
jsobj.AddProperty("is_optimizable", is_optimizable());
jsobj.AddProperty("is_inlinable", IsInlineable());
- const char* kind_string = NULL;
- switch (kind()) {
- case RawFunction::kRegularFunction:
- kind_string = "regular";
- break;
- case RawFunction::kGetterFunction:
- kind_string = "getter";
- break;
- case RawFunction::kSetterFunction:
- kind_string = "setter";
- break;
- case RawFunction::kImplicitGetter:
- kind_string = "implicit getter";
- break;
- case RawFunction::kImplicitSetter:
- kind_string = "implicit setter";
- break;
- case RawFunction::kMethodExtractor:
- kind_string = "method extractor";
- break;
- case RawFunction::kNoSuchMethodDispatcher:
- kind_string = "no such method";
- break;
- case RawFunction::kClosureFunction:
- kind_string = "closure";
- break;
- case RawFunction::kConstructor:
- kind_string = "constructor";
- break;
- case RawFunction::kStaticInitializer:
- kind_string = "static initializer";
- break;
- case RawFunction::kImplicitStaticFinalGetter:
- kind_string = "static final getter";
- break;
- default:
- UNREACHABLE();
- }
+ const char* kind_string = Function::KindToCString(kind());
jsobj.AddProperty("kind", kind_string);
jsobj.AddProperty("unoptimized_code", Object::Handle(unoptimized_code()));
jsobj.AddProperty("usage_counter", usage_counter());
@@ -9691,10 +9823,26 @@ void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const {
}
-void Code::Disassemble() const {
+void Code::Disassemble(DisassemblyFormatter* formatter) const {
+ const bool fix_patch = CodePatcher::CodeIsPatchable(*this) &&
+ CodePatcher::IsEntryPatched(*this);
+ if (fix_patch) {
+ // The disassembler may choke on illegal instructions if the code has been
+ // patched, un-patch the code before disassembling and re-patch after.
+ CodePatcher::RestoreEntry(*this);
+ }
const Instructions& instr = Instructions::Handle(instructions());
uword start = instr.EntryPoint();
- Disassembler::Disassemble(start, start + instr.size(), comments());
+ if (formatter == NULL) {
+ Disassembler::Disassemble(start, start + instr.size(), comments());
+ } else {
+ Disassembler::Disassemble(start, start + instr.size(), formatter,
+ comments());
+ }
+ if (fix_patch) {
+ // Redo the patch.
+ CodePatcher::PatchEntry(*this);
+ }
}
@@ -9876,16 +10024,16 @@ const char* Code::ToCString() const {
void Code::PrintToJSONStream(JSONStream* stream, bool ref) const {
- Isolate* isolate = Isolate::Current();
- ObjectIdRing* ring = isolate->object_id_ring();
- intptr_t id = ring->GetIdForObject(raw());
JSONObject jsobj(stream);
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddPropertyF("id", "objects/%" Pd "", id);
+ jsobj.AddPropertyF("id", "code/%" Px "", EntryPoint());
+ jsobj.AddPropertyF("start", "%" Px "", EntryPoint());
+ jsobj.AddPropertyF("end", "%" Px "", EntryPoint() + Size());
Function& func = Function::Handle();
- String& name = String::Handle();
func ^= function();
ASSERT(!func.IsNull());
+ String& name = String::Handle();
+ ASSERT(!func.IsNull());
name ^= func.name();
const char* internal_function_name = name.ToCString();
jsobj.AddPropertyF("name", "%s%s", is_optimized() ? "*" : "",
@@ -9902,10 +10050,7 @@ void Code::PrintToJSONStream(JSONStream* stream, bool ref) const {
jsobj.AddProperty("function", Object::Handle(function()));
JSONArray jsarr(&jsobj, "disassembly");
DisassembleToJSONStream formatter(jsarr);
- const Instructions& instr = Instructions::Handle(instructions());
- uword start = instr.EntryPoint();
- Disassembler::Disassemble(start, start + instr.size(), &formatter,
- comments());
+ Disassemble(&formatter);
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698